问题
我正在从基本R
过渡到dplyr
。
为了遵守DRY(Don't Repeat Yourself)原则,我想缩短以下代码:
mtcars %>% mutate(w = rowMeans(select(., mpg:disp), na.rm = TRUE),
x = rowMeans(select(., hp:wt), na.rm = TRUE),
y = rowMeans(select(., qsec:am), na.rm = TRUE),
z = rowMeans(select(., gear:carb), na.rm = TRUE))
或
mtcars %>% rowwise() %>% mutate(w = mean(mpg:disp, na.rm = TRUE),
x = mean(hp:wt, na.rm = TRUE),
y = mean(qsec:am, na.rm = TRUE),
z = mean(gear:carb, na.rm = TRUE))
# Note: this one produced an error with my own data
目标
目标是从单个调用计算 Dataframe 中不同尺度的均值。如您所见,rowMeans
、select
和na.rm
参数重复了几次(假设我有比本例多几个变量)。
尝试次数
I was trying试to come up with an across()
解决方案,
mtcars %>% mutate(across(mpg:carb, mean, .names = "mean_{col}"))
但是它没有产生正确的结果,因为我不知道如何为w:z
指定不同的列参数。使用文档示例中的c_across
,我们回到重复代码:
mtcars %>% rowwise() %>% mutate(w = mean(c_across(mpg:disp), na.rm = TRUE),
x = mean(c_across(hp:wt), na.rm = TRUE),
y = mean(c_across(qsec:am), na.rm = TRUE),
z = mean(c_across(gear:carb), na.rm = TRUE))
我很想求助于lapply
或一个自定义函数,但我觉得这会破坏适应dplyr
和新的across()
参数的目的。
4条答案
按热度按时间qv7cva1a1#
我们不需要
rowwise
,而是使用select
和矢量化的rowMeans
。为了使这更容易,可以创建一个函数kqqjbcuj2#
使用自定义函数(但组织方式略有不同,以减少重复代码)
7y4bm7vi3#
考虑使用
purrr::reduce2
来避免重复ryevplcw4#
从
dplyr 1.1.0
开始使用新的pick()
函数的新的略短的解决方案:说明:新的
pick()
函数现在允许我们避免像在select()
中那样指定dot参数。创建于2023-05-19带有reprex v2.0.2