7

我将使用以下数据集来说明我的问题:

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和的均值,而仅包含s。在研究了一下代码之后,我理解了第二个问题。函数中添加的“ ”是指原始数据框,没有and列。所以产生 s 是有道理的,因为我要求计算不存在值的均值。b_2NaN.select()my_dfa_2b_2NaNR

然后我尝试使用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()andmean()函数。但是再一次,我想为此使用其中一个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()我怀疑代码中的错误是由于不在 inside的事实select(),但我展示这个是为了询问是否有一种方法可以列出我想要的变量而不必单独指定它们。

感谢您的时间。

4

2 回答 2

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 比较棘手,而且可能不理想(?)

于 2018-06-18T19:14:03.483 回答
0

幸运的是,由于 dplyr > 1.0.0,有一种 dplyr 方式可以通过使用 c_across 来完成您正在寻找的事情。这很有帮助,因为它将解决方案扩展到可能具有 Row 实现的其他函数,例如 RowMeans()。

尝试这个:

my_df %>%
  mutate(
    a_2 = a^2,
    b_2 = b^2,
    ) %>% 
  rowwise() %>% 
  mutate( mean = mean(c_across(ends_with("2"))) )
于 2022-02-01T20:46:00.470 回答