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仅被定义为我的数据框的列?
这与工作原理无关,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/y和x-y作为yes和no参数时,由于checkVar == 1返回TRUE(标量),ifelse返回(x/y)[1],即矢量的第一个元素x/y,这是11和得到回收填充新列z;
在你的第二个案例,mutate并ifelse在每行执行,所以它的评价5次,每一次返回的值,x/y该行。
如果您的条件是标量,那么您不需要vectorized ifelse,if/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)