2017-10-06 100 views
0

我很好奇为什么dplyr::mutate()呼叫内的ifelse()声明似乎只适用于我的数据帧的第一行。这会返回一个值,它会在整个列中循环使用。由于在ifelse()的任一情况下评估的表情只在我的数据帧的情况下有效,我希望被列上作为一个整体进行健康检查,并导致表达的评价,而不仅仅是他们的第一要素。[R dplyr ::与ifelse条件在全局变量变异回收结果从第一行

下面是一个例子:我的数据帧之外定义的变量称为checkVar。取决于checkVar的价值,我想不同的充值在新列,z,被计算为现有列的功能添加到我的数据帧。

如果我做

checkVar <- 1 
df <- data.frame(x=11:15, y=1:5) %>% 
    dplyr::mutate(z=ifelse(checkVar == 1, x/y, x-y)) 
df 

返回

x y z 
1 11 1 11 
2 12 2 11 
3 13 3 11 
4 14 4 11 
5 15 5 11 

相反的z是x和y的每一行的商,所有行填充x的商和y从数据帧的第一行。

但是,如果我指定rowwise(),我得到了我想要的结果:

df <- df %>% 
    dplyr::rowwise() %>% 
    dplyr::mutate(z=ifelse(checkVar == 1, x/y, x-y)) %>% 
    dplyr::ungroup() 
df 

回报

# A tibble: 5 x 3 
     x  y   z 
    <int> <int>  <dbl> 
1 11  1 11.000000 
2 12  2 6.000000 
3 13  3 4.333333 
4 14  4 3.500000 
5 15  5 3.000000 

为什么我必须明确指定rowwise()xy只能定义为列我的数据框?

+0

'checkVar'是length' 1.本的',我相信,只会导致使用'x'和'y'的第一行。如果你设置了'checkVar < - rep(1,5)',你会得到你想要的结果。如果你使用'dplyr'的'if_else',它会告诉你问题是什么。另外,使用'rowwise'使得'ifelse'中的所有内容长度都是1. – Abdou

+0

如果你使用'ifelse'的dplyr版本,它是'if_else',那么你得到错误'“true是长度5而不是1或1.“'。 – Marek

回答

3

这是不是真的与dplyr::mutate,但如何ifelse作品,这里是文档ifelse

ifelse形状相同返回值作为测试,与选定的元素来填充 是或否,具体取决于测试的 元素是TRUE还是FALSE。

用法

ifelse(测试,是,否)

而且例如:

ifelse(T, c(1,2,3), c(2,3,4)) 
# [1] 1 

你的第一种情况下被矢量,ifelse取矢量x/yx-yyesno参数由于checkVar == 1回报TRUE (标量),ifelse返回(x/y)[1],即矢量x/y的第一个元素,即并被循环填充新列z;

在你的第二个情况下,mutateifelse每行被执行,所以它的评估次,每次返回x/y该行的值。


如果你的条件是标量,那么你不需要矢量ifelseif/else更适合使用:

checkVar <- 1 
mutate(df, z = if(checkVar == 1) x/y else x-y) 

# x y   z 
#1 11 1 11.000000 
#2 12 2 6.000000 
#3 13 3 4.333333 
#4 14 4 3.500000 
#5 15 5 3.000000 
+0

你最后一个例子非常有趣。我甚至不知道你可以在调用mutate后在赋值的右边使用标准的if/else结构。感谢发布;这是非常好的知道! – bmosov01

+0

可选:'mutate(z = case_when(checkVar == 1〜x/y,TRUE〜as.numeric(x-y)))' – Marek

+0

@ bmosov01很高兴帮助! – Psidom