当突变是有条件的(取决于某些列值的值)时,是否可以使用mutate?
这个例子有助于显示我的意思 .
structure(list(a = c(1, 3, 4, 6, 3, 2, 5, 1), b = c(1, 3, 4,
2, 6, 7, 2, 6), c = c(6, 3, 6, 5, 3, 6, 5, 3), d = c(6, 2, 4,
5, 3, 7, 2, 6), e = c(1, 2, 4, 5, 6, 7, 6, 3), f = c(2, 3, 4,
2, 2, 7, 5, 2)), .Names = c("a", "b", "c", "d", "e", "f"), row.names = c(NA,
8L), class = "data.frame")
a b c d e f
1 1 1 6 6 1 2
2 3 3 3 2 2 3
3 4 4 6 4 4 4
4 6 2 5 5 5 2
5 3 6 3 3 6 2
6 2 7 6 7 7 7
7 5 2 5 2 6 5
8 1 6 3 6 3 2
我希望使用dplyr包找到解决我的问题的方法(是的,我知道这不是代码应该有用,但我想它的目的很明确)用于创建新列g:
library(dplyr)
df <- mutate(df,
if (a == 2 | a == 5 | a == 7 | (a == 1 & b == 4)){g = 2},
if (a == 0 | a == 1 | a == 4 | a == 3 | c == 4) {g = 3})
我正在寻找的代码的结果应该在这个特定的例子中有这个结果:
a b c d e f g
1 1 1 6 6 1 2 3
2 3 3 3 2 2 3 3
3 4 4 6 4 4 4 3
4 6 2 5 5 5 2 NA
5 3 6 3 3 6 2 NA
6 2 7 6 7 7 7 2
7 5 2 5 2 6 5 2
8 1 6 3 6 3 2 3
有没有人知道如何在dplyr中这样做?这个数据框只是一个例子,我正在处理的数据框要大得多 . 由于它的速度,我试图使用dplyr,但也许还有其他更好的方法来处理这个问题?
5 回答
在以下情况下,
case_when
现在是SQL风格案例的一个非常干净的实现:使用dplyr 0.7.4
手册:http://dplyr.tidyverse.org/reference/case_when.html
使用
ifelse
Added - if_else: 请注意,在dplyr 0.5中定义了
if_else
函数,因此替代方法是将ifelse
替换为if_else
;但请注意,由于if_else
比ifelse
更严格(条件的两条腿必须具有相同的类型)所以NA
在这种情况下必须用NA_real_
替换 .Added - case_when 自发布此问题以来,dplyr已添加了
case_when
,因此另一种选择是:mosaic
包中的derivedFactor
函数似乎是为了解决这个问题而设计的 . 使用此示例,它看起来像:(如果您希望结果为数字而不是因子,则可以在
as.numeric
调用中包装derivedFactor
. )derivedFactor
也可以用于任意数量的条件 .dplyr现在有一个函数
case_when
,提供了vectorised if . 与mosaic:::derivedFactor
相比,语法有点奇怪,因为您无法以标准dplyr方式访问变量,并且需要声明NA的模式,但它比mosaic:::derivedFactor
快得多 .EDIT: 如果您使用的是包之前版本0.7.0之前的
dplyr::case_when()
,则需要在变量名前加上'.$
'(例如在case_when
内写入.$a == 1
) .Benchmark :对于基准测试(重用Arun的帖子中的函数)和减少样本量:
这给出了:
既然你要求其他更好的方法来处理这个问题,这是使用
data.table
的另一种方式:请注意,条件语句的顺序相反,以正确获取
g
. 即使在第二次任务期间,也没有g
的副本 - 它已就地替换 .在较大的数据上,这将比使用嵌套的
if-else
具有更好的性能,如it can evaluate both 'yes' and 'no' cases,并且嵌套可能更难以读取/维护恕我直言 .这是相对较大数据的基准:
不确定这是否是您要求的替代品,但我希望它有所帮助 .