【发布时间】:2018-03-18 18:01:49
【问题描述】:
我很好奇为什么调用dplyr::mutate() 中的ifelse() 语句似乎只适用于我的数据框的第一行。这将返回一个值,该值在整个列中循环使用。由于在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
当x 和y 仅定义为我的数据框的列时,为什么我必须明确指定rowwise()?
【问题讨论】:
-
checkVar属于length1。我相信,这只会导致第一行x和y被使用。如果你设置checkVar <- rep(1,5),你会得到你想要的输出。如果您使用dplyr的if_else,它会告诉您问题所在。此外,使用rowwise可以使ifelse中的所有内容的长度为1。 -
如果你使用
ifelse的dplyr版本,即if_else,那么你会得到错误"true is length 5 not 1 or 1."。
标签: r conditional vectorization dplyr