R dplyr::mutate with ifelse 以全局变量为条件从第一行回收结果

bmo*_*v01 2 conditional r vectorization dplyr mutate

我很好奇为什么ifelse()调用中的语句dplyr::mutate()似乎只适用于我的数据框的第一行。这将返回一个值,该值在整个列中循环使用。由于在这两种情况下评估的表达式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
Run Code Online (Sandbox Code Playgroud)

它返回

   x y  z
1 11 1 11
2 12 2 11
3 13 3 11
4 14 4 11
5 15 5 11
Run Code Online (Sandbox Code Playgroud)

z 不是每行的 x 和 y 的商,而是所有行都填充有来自数据帧第一行的 x 和 y 的商。

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

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

返回

# 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
Run Code Online (Sandbox Code Playgroud)

为什么我必须明确指定rowwise()何时x并且y仅被定义为我的数据框的列?

Psi*_*dom 6

这与工作原理无关,dplyr::mutate但与ifelse工作原理无关,这里是文档?ifelse

ifelse 返回一个与 test 具有相同形状的值,其中填充了从 yes 或 no 中选择的元素,具体取决于 test 的元素是 TRUE 还是 FALSE。

用法

ifelse(测试,是,否)

和例子:

ifelse(T, c(1,2,3), c(2,3,4))
# [1] 1
Run Code Online (Sandbox Code Playgroud)

您的第一种情况下被矢量,ifelse采用矢量x/yx-y作为yesno参数时,由于checkVar == 1返回TRUE(标量),ifelse返回(x/y)[1],即矢量的第一个元素x/y,这是11和得到回收填充新列z;

在你的第二个案例,mutateifelse在每行执行,所以它的评价5次,每一次返回的值,x/y该行。


如果您的条件是标量,那么您不需要vectorized 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
Run Code Online (Sandbox Code Playgroud)