dplyr中mutate_each的意外行为 - 变异中使用的variabel变异

时间:2015-10-05 18:58:46

标签: r dplyr

我在dplyr中遇到了意外行为。我试图通过其中一个变量的值来加权数据集中的所有变量。这是饮食数据,每份食物的营养价值。服务的重量是已知的,我希望分析每克食物的价值,而不是每份食物。

服务权重是数据集中的第十个数字变量。前九个被正确转换。权重变量也正确地设置为1.后续变量保持不变(或可能除以1)。这不是预期的!

可以通过在数据框末尾创建一个新变量来修复问题,保留服务权重变量的值。它也可以通过将权重变量保留在mutate语句之外来修复,但我选择不执行此操作,因为它提供了有用的检查。

这是一个简短的例子,说明了我的观点: -

library(dplyr)
a <- letters[1:6]
x1 <- rep(1,6);x2 <- rep(2,6);x3 <- rep(3,6)
x4 <- rep(4,6);x5 <- rep(5,6);x6 <- rep(6,6)
#I want to divide each variable by one of the variables - Two examples
d <- data.frame(a,x1,x2,x3,x4,x5,x6)
d %>% mutate_each(funs(Weight = ./x3),x1:x6) #Unexpected!
d %>% mutate_each(funs(Weight = ./x4),x1:x6) #Unexpected!

输出:

  a        x1        x2 x3 x4 x5 x6
1 a 0.3333333 0.6666667  1  4  5  6
2 b 0.3333333 0.6666667  1  4  5  6
3 c 0.3333333 0.6666667  1  4  5  6
4 d 0.3333333 0.6666667  1  4  5  6
5 e 0.3333333 0.6666667  1  4  5  6
6 f 0.3333333 0.6666667  1  4  5  6

     a   x1  x2   x3 x4 x5 x6
1 a 0.25 0.5 0.75  1  5  6
2 b 0.25 0.5 0.75  1  5  6
3 c 0.25 0.5 0.75  1  5  6
4 d 0.25 0.5 0.75  1  5  6
5 e 0.25 0.5 0.75  1  5  6
6 f 0.25 0.5 0.75  1  5  6
  

解决方法:

#Make a new variable at the end of the data frame
d$Three <- d$x3
d$Four <- d$x4

d %>% mutate_each(funs(Weight = ./Three),x1:x6) #Expected!
d %>% mutate_each(funs(Weight = ./Four),x1:x6) #Expected!

输出:

  a        x1        x2 x3       x4       x5 x6 Three Four
1 a 0.3333333 0.6666667  1 1.333333 1.666667  2     3    4
2 b 0.3333333 0.6666667  1 1.333333 1.666667  2     3    4
3 c 0.3333333 0.6666667  1 1.333333 1.666667  2     3    4
4 d 0.3333333 0.6666667  1 1.333333 1.666667  2     3    4
5 e 0.3333333 0.6666667  1 1.333333 1.666667  2     3    4
6 f 0.3333333 0.6666667  1 1.333333 1.666667  2     3    4

  a   x1  x2   x3 x4   x5  x6 Three Four
1 a 0.25 0.5 0.75  1 1.25 1.5     3    4
2 b 0.25 0.5 0.75  1 1.25 1.5     3    4
3 c 0.25 0.5 0.75  1 1.25 1.5     3    4
4 d 0.25 0.5 0.75  1 1.25 1.5     3    4
5 e 0.25 0.5 0.75  1 1.25 1.5     3    4
6 f 0.25 0.5 0.75  1 1.25 1.5     3    4

这是有道理的,因为dplyr允许您在进行时创建和使用新变量。然而,对我来说,这种特定的行为是违反直觉的,也许是因为我总是认为突变是原子的。在这种情况下,他们不是!

我想我现在可能已经回答了我原来的问题,但我会在这里发布其他人被同样的行为所咬。这有意义吗?我是否正确理解了这种行为?

1 个答案:

答案 0 :(得分:1)

另一种解决方法是引用数据框spark前面的变量。因为默认情况下它会应用于所有非分组变量,所以我们只排除列d$x3以避免将因子除以数字并生成NA:

-a

输出:

d %>% mutate_each(funs(Weight = ./d$x3), -a)

如果我们要分组,那么我们需要使用scoa指示的方法,排除该变量,因为 a x1 x2 x3 x4 x5 x6 1 a 0.3333333 0.6666667 1 1.333333 1.666667 2 2 b 0.3333333 0.6666667 1 1.333333 1.666667 2 3 c 0.3333333 0.6666667 1 1.333333 1.666667 2 4 d 0.3333333 0.6666667 1 1.333333 1.666667 2 5 e 0.3333333 0.6666667 1 1.333333 1.666667 2 6 f 0.3333333 0.6666667 1 1.333333 1.666667 2 会产生错误。请注意,因为我们按变量d$x3进行分组,所以这次不需要排除它。

a

输出:

d %>% group_by(a) %>% mutate_each(funs(Weight = ./x3), -x3)