我正在根据另一个的TRUE / FALSE状态计算一个新变量:
value<-c(2, 4, 5, 8, 2, 3, 1)
tf<-c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE)
df<-data.frame(value, tf)
以下代码可以满足我的需要(如果'tf'为TRUE,那么将'值'减半'...
df$newVals[which(df$tf)]<-df$value[which(df$tf)]/2
df$newVals[which(!df$tf)]<-df$value[which(!df$tf)]
......但感觉太复杂了。有更简单的方法吗?
由于
答案 0 :(得分:8)
这是一个非常简单的解决方案,没有ifelse
:
df$newVals <- with(df, value / (tf + 1))
它如何运作?
如果布尔值(如tf
)与数学运算符一起使用,则会将它们转换为数值(FALSE
转换为0
,TRUE
转换为{ {1}})。因此,命令1
创建了tf + 1
s和1
s的数字向量。 2
中的值除以此新向量中的值。除以1不会改变原始值。
答案 1 :(得分:6)
您可以使用ifelse
:
value<-c(2, 4, 5, 8, 2, 3, 1)
tf<-c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE)
df<-data.frame(value, tf)
df$newVals <- with(df, ifelse(tf, value/2, value))
答案 2 :(得分:4)
使用ifelse
和transform
将为您完成
transform(df, newVals=ifelse(tf, value/2,value))
value tf newVals
1 2 TRUE 1.0
2 4 FALSE 4.0
3 5 FALSE 5.0
4 8 FALSE 8.0
5 2 TRUE 1.0
6 3 FALSE 3.0
7 1 TRUE 0.5
答案 3 :(得分:1)
略有不同的粘性;只需更新需要更改的值而不是所有值,然后使用ifelse()
从中进行选择。 E.g。
value<-c(2, 4, 5, 8, 2, 3, 1)
tf<-c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE)
df<-data.frame(value, tf)
df <- transform(df, newVals = value) ## task a copy of `value`
df[df$tf, "newVals"] <- df[df$tf, "value"] / 2 ## update only ones we want
df
给予
> df
value tf newVals
1 2 TRUE 1.0
2 4 FALSE 4.0
3 5 FALSE 5.0
4 8 FALSE 8.0
5 2 TRUE 1.0
6 3 FALSE 3.0
7 1 TRUE 0.5
如果您不喜欢所有索引,可以稍微分解一下 - 只需创建ind
,其中包含tf
为TRUE
的行的索引:
df <- transform(df, newVals = value)
ind <- with(df, which(tf))
df[ind, "newVals"] <- df[ind, "value"] / 2
df
> df
value tf newVals
1 2 TRUE 1.0
2 4 FALSE 4.0
3 5 FALSE 5.0
4 8 FALSE 8.0
5 2 TRUE 1.0
6 3 FALSE 3.0
7 1 TRUE 0.5