我想基于多个列(即多个条件)的特定值执行rowSums
。我知道如何根据一个条件rowSums
(请参见下面的示例),但似乎无法弄清楚多个条件。
# rowSums with single, global condition
set.seed(100)
df <- data.frame(a = sample(0:100,10),
b = sample(0:100,10),
c = sample(0:100,10),
d = sample(0:100,10))
print(df)
a b c d
1 31 63 54 49
2 25 88 71 92
3 54 27 53 34
4 5 39 73 93
5 45 73 40 67
6 46 64 16 85
7 77 19 97 17
8 34 33 82 59
9 50 93 51 99
10 15 100 25 11
单个条件有效
df$ROWSUMS <- rowSums(df[,1:4] <= 50)
# And produces
a b c d ROWSUMS
1 31 63 54 49 2
2 25 88 71 92 1
3 54 27 53 34 2
4 5 39 73 93 2
5 45 73 40 67 2
6 46 64 16 85 2
7 77 19 97 17 2
8 34 33 82 59 2
9 50 93 51 99 1
10 15 100 25 11 3
多个条件不起作用
df$ROWSUMS_Multi <- rowSums(df[,1] <= 50 | df[,2] <= 25 | df[,3] <= 75)
rowSums(df [,1] <= 50 | df [,2] <= 25 | df [,3] <= 75)中的错误: “ x”必须是至少二维的数组
所需的输出
a b c d ROWSUMS_Multi
1 31 63 54 49 2
2 25 88 71 92 2
3 54 27 53 34 1
4 5 39 73 93 2
5 45 73 40 67 2
6 46 64 16 85 2
7 77 19 97 17 1
8 34 33 82 59 1
9 50 93 51 99 2
10 15 100 25 11 2
我可能只是错误地设置了子设置,但我无法找到修复程序。
答案 0 :(得分:4)
[
在具有单行或单列时的一个问题是将data.frame
强制为向量。基于?Extract
x [i,j,...,drop = TRUE]
注意,drop
默认为TRUE
以及随后的文档中
drop-用于矩阵和数组。如果为TRUE,则结果强制为最小尺寸(请参见示例)。这仅适用于提取元素,不适用于替换。有关更多详细信息,请参见drop。
为避免这种情况,请使用drop = FALSE
或简单地删除,
,这将返回单个列data.frame,因为默认情况下,不带逗号的索引被视为列索引,而不是行索引data.frame
rowSums(df[1] <= 50 | df[2] <= 25 | df[3] <= 75)
根据预期的输出,rowSums
可以写为
dfROWSUMS <- rowSums(df[1:3] <= c(50, 25, 75)[col(df[1:3])])
df$ROWSUMS
#[1] 2 2 1 2 2 2 1 1 2 2
注意:较早的评论基于rowSums
不起作用的原因。之前没有检查预期的输出。在这里,我们需要对具有不同值的3列进行比较。当我们这样做
df[1] <= 50
它是一个包含TRUE / FALSE的单列
当我们用|
做
df[1] <= 50 | df[2] <= 25
它仍然是TRUE / FALSE的单个列。唯一的区别是我们用TRUE/FALSE
连续替换了FALSE/TRUE
或TRUE
。同样,与n
相比,我们添加|
逻辑比较也会是这种情况。取而代之的是,执行+
,按元素求和
((df[1] <= 50)+ (df[2] <= 25) + (df[3] <= 75))[,1] # note it is a matrix
在这里,我们可以使用vector
进行操作,即也可以使用,
((df[, 1] <= 50)+ (df[, 2] <= 25) + (df[, 3] <= 75)) # vector output
唯一的问题是重复执行+
。如果使用rowSums
,请确保将比较值复制(col
)到data.frame子集的相同维度。另一个选项是Map
,
Reduce(`+`, Map(`<=`, df[1:3], c(50, 25, 75)))
答案 1 :(得分:1)
我们还可以使用cbind
从使用列位置或列名的多个条件创建矩阵,然后像往常一样使用rowSums
,例如
> rowSums(cbind(df[,'a'] <= 50 ,df[,'b'] <= 25 ,df[,'c'] <= 75), na.rm = TRUE)
[1] 2 2 1 2 2 2 1 1 2 2
> rowSums(cbind(df['a'] <= 50 ,df['b'] <= 25 ,df['c'] <= 75), na.rm = TRUE)
[1] 2 2 1 2 2 2 1 1 2 2
使用dplyr
library(dplyr)
df %>% mutate(ROWSUMS=rowSums(cbind(.['a'] <= 50 ,.['b'] <= 25 ,.['c'] <= 75), na.rm = TRUE))