【发布时间】:2015-06-17 16:31:31
【问题描述】:
我经常需要根据因子变量的条件从数据框中的现有变量中计算新变量。
编辑 在 2 分钟内得到 4 个答案,我意识到我的例子过于简单化了。请看下文。
简单示例:
df <- data.frame(value=c(1:5),class=letters[1:5])
df
value class
1 a
2 b
3 c
4 d
5 e
我可以使用这样的代码
df %>%
mutate(result=NA) %>%
mutate(result=ifelse(class=="a",value*1,result)) %>%
mutate(result=ifelse(class=="b",value*2,result)) %>%
mutate(result=ifelse(class=="c",value*3,result)) %>%
mutate(result=ifelse(class=="d",value*4,result)) %>%
mutate(result=ifelse(class=="e",value*5,result))
对我的变量执行条件计算,导致
value class result
1 a 1
2 b 4
3 c 9
4 d 16
5 e 25
实际上,类的数量更大,计算更复杂,但是,我更喜欢更干净的东西,比如这样
df %>%
mutate(results=switch(levels(class),
"a"=value*1,
"b"=value*2,
"c"=value*3,
"d"=value*4,
"e"=value*5))
这显然行不通
Error in switch(levels(1:5), a = 1:5 * 1, b = 1:5 * 2, c = 1:5 * 3, d = 1:5 * :
EXPR must be a length 1 vector
有没有办法让我用 dplyr 管道(或其他)更好地做到这一点?
编辑 实际上,我的计算中包含更多的值变量,它们不是简单的连续向量,它们是数千行测量数据。
这是我的简单示例,带有第二个随机值变量(同样,它更多地存在于我的真实数据中)
df <- data.frame(value1=c(1:5),value2=c(2.3,3.6,7.2,5.6,0),class=letters[1:5])
value1 value2 class
1 2.3 a
2 3.6 b
3 7.2 c
4 5.6 d
5 0.0 e
我的计算因每种情况而异。我知道我可以像这样简化一些
df %>%
mutate(result=NA,
result=ifelse(class=="a",value1*1,result),
result=ifelse(class=="b",value1/value2*4,result),
result=ifelse(class=="c",value2*3.57,result),
result=ifelse(class=="d",value1+value2*2,result),
result=ifelse(class=="e",value2/value1/5,result))
不过,类似于上述 switch 示例的可行解决方案会更加简洁。
【问题讨论】:
-
omg,你太快了......而且我对我的实际问题进行了简单的简化。在发布新解决方案之前,请给我一些时间进行编辑...
-
不需要多个mutates,你可以在同一个mutate中引用“新鲜”变量,即:
mutate(result=NA, result=ifelse(class=="a",value*1,result)), result= ... ) -
谢谢,我在编辑中加入了这个。我同意一些改进,但它可以更清洁吗?
-
嘿,在此编辑之后,没有任何解决方案可以工作......
-
和this question差不多。