我下面有一个数据集:
Col1 Col2 Spend
A 0 100
A 0 100
B 0 100
C 0 100
D 0 200
我想写一条ifelse语句,说明如果Col2的总和大于0,则设置Col2 = Spend。如果Col2的总和不大于0,则仅将“支出列”应用于值不等于A
的相应行,其余部分保留为Col2原始值。
我希望我的最终输出看起来像这样:
Col1 Col2 Spend
A 0 100
A 0 100
B 100 100
C 100 100
D 200 200
我认为应该是这样的:
df$Col2 <- ifelse(sum(df$Col2)>0, df$Spend, ifelse(df$Col1!="A", df$Spend, df$Col2))
我的问题是,当我运行此命令时,我再次检查Col2的总和,但它仍然没有变化。不知道我在这里做错了什么。
答案 0 :(得分:3)
数据集
df = read.table(text = "
Col1 Col2 Spend
A 0 100
A 0 100
B 0 100
C 0 100
D 0 200
", header=T)
问题
如果运行代码,您会看到它返回一个0
值,然后将其复制以适合列的长度。这不会返回五个0
。
ifelse(sum(df$Col2)>0, df$Spend, ifelse(df$Col1!="A", df$Spend, df$Col2))
# [1] 0
之所以会这样,是因为您从?ifelse
中看到“ ifelse返回的值与test具有相同的形状...”,而您的{test} sum(df$Col2)>0
将仅返回一个值,因为{{ 1}}是一个值(即总和)。
解决方案
您可以将sum(df$Col2)
语句与嵌套的if ... else
一起使用,如下所示:
ifelse
因此,您检查(您的测试)if (sum(df$Col2)>0) df$Spend else ifelse(df$Col1!="A", df$Spend, df$Col2)
# [1] 0 0 100 100 200
是否为真,然后返回整个sum(df$Col2)>0
列,否则继续执行Spend
语句。
答案 1 :(得分:1)
此问题与R处理向量化操作的方式有关,因为ifelse
语句的第一个参数返回长度为1的逻辑(因为sum(df$Col2) > 0
仅返回True
,{ {1}}或False
)中,只有一个值正在使用中。
这将是正在发生的事
NA
因此,您的示例将通过更改语法来解决
> ifelse(TRUE, 1:4, 1:4)
[1] 1
> ifelse(c(TRUE, TRUE, FALSE, FALSE), 1:4, 1:4)
[1] 1 2 3 4
如果您真的想要单线纸
if (sum(df$Col2)>0) {
df$Col2 <- df$Spend
} else {
df$Col2 <- ifelse(df$Col1!="A", df$Spend, df$Col2)
}