我将使用以下数据集来说明我的问题:
my_df <- data.frame(
a = 1:10,
b = 10:1
)
colnames(my_df) <- c("a", "b")
第1部分
我使用mutate()
函数在我的数据集中创建两个新变量,我想计算同一mutate()
调用中两个新列的行方式。但是,我真的希望能够使用select()
,starts_with()
或ends_with()
等contains()
助手。
我的第一次尝试:
my_df %>%
mutate(
a_2 = a^2,
b_2 = b^2,
mean = rowMeans(select(ends_with("2")))
)
Error in mutate_impl(.data, dots) :
Evaluation error: No tidyselect variables were registered.
我理解为什么会出现错误 - select()
函数没有给出任何.data
参数。所以我改变了......中的代码。
...我的第二次尝试是在.
函数中添加“select()
”:
my_df %>%
mutate(
a_2 = a^2,
b_2 = b^2,
mean = rowMeans(select(., ends_with("2")))
)
a b a_2 b_2 mean
1 1 10 1 100 NaN
2 2 9 4 81 NaN
3 3 8 9 64 NaN
4 4 7 16 49 NaN
5 5 6 25 36 NaN
6 6 5 36 25 NaN
7 7 4 49 16 NaN
8 8 3 64 9 NaN
9 9 2 81 4 NaN
10 10 1 100 1 NaN
第二次尝试后的新问题是mean
列未按预期包含a_2
和b_2
的平均值,但仅包含NaN
s。在研究了一下代码之后,我理解了第二个问题。 .
函数中添加的“select()
”指的是原始my_df
数据框,其中没有a_2
和b_2
列。因此,生成NaN
是有道理的,因为我要求R
计算不存在的值的均值。
然后我尝试使用dplyr
等current_vars()
函数来查看它是否会产生影响:
my_df %>%
mutate(
a_2 = a^2,
b_2 = b^2,
mean = rowMeans(select(current_vars(), ends_with("2")))
)
Error in mutate_impl(.data, dots) :
Evaluation error: Variable context not set.
但是,这显然不是使用此功能的方法。解决方案是简单地添加第二个mutate()
函数:
my_df %>%
mutate(
a_2 = a^2,
b_2 = b^2
) %>%
mutate(mean = rowMeans(select(., ends_with("2"))))
a b a_2 b_2 mean
1 1 10 1 100 50.5
2 2 9 4 81 42.5
3 3 8 9 64 36.5
4 4 7 16 49 32.5
5 5 6 25 36 30.5
6 6 5 36 25 30.5
7 7 4 49 16 32.5
8 8 3 64 9 36.5
9 9 2 81 4 42.5
10 10 1 100 1 50.5
问题1:有没有办法在同一个mutate()
电话中执行此任务?无论如何,使用第二个mutate()
函数并不是真正的问题;但是,我很想知道是否存在引用当前存在的变量的方法。 mutate()
函数允许在同一mutate()
次调用中创建变量后立即使用变量;但是,当函数嵌套时,如上例所示,这就成了问题。
第2部分
我也意识到使用rowMeans()
在我的解决方案中起作用;然而,它并不是一种dplyr
- 做事的方式,特别是因为我需要在其中使用select()
。所以,我决定使用rowwise()
和mean()
函数。但是我再次使用其中一个select()
助手,而不必列出c()
函数中的所有变量。我试过了:
my_df %>%
mutate(
a_2 = a^2,
b_2 = b^2
) %>%
rowwise() %>%
mutate(
mean = mean(ends_with("2"))
)
Error in mutate_impl(.data, dots) :
Evaluation error: No tidyselect variables were registered.
我怀疑代码中的错误是由于ends_with()
不在select()
内部的事实,但是我正在展示这是否有办法列出我想要的变量必须单独指定它们。
感谢您的时间。
答案 0 :(得分:2)
有点晚了,但这是问题1的解决方案,供参考。
如果你必须在没有管道的情况下这样做,你会写:
tmp1 = mutate(my_df, a_2 = a^2, b_2 = b^2)
tmp2 = select(tmp1, ends_with("2"))
tmp3 = rowMeans(tmp2)
tmp4 = mutate(tmp1, m=tmp3)
或者,中间步骤较少:
tmp1 = mutate(my_df, a_2 = a^2, b_2 = b^2)
tmp4 = mutate(tmp1, m=rowMeans(select(tmp1, ends_with("2"))) )
请注意,计算tmp4
需要两次使用tmp1
。因此,在管道版本中,您还需要第二次显式引用.
(通常第一个引用是隐式的,作为mutate的第一个参数):
my_df %>%
mutate(a_2 = a^2, b_2 = b^2) %>%
mutate(mean = rowMeans(select(., ends_with("2"))) )
对于问题#2:避免调用rowMeans比较棘手,也许不可取(?)