按条件(>)计算每行的列数

37

我正在尝试计算矩阵每一行中有多少个值大于指定值。非常抱歉我要问这么简单的问题,但是我无法弄清楚。

我从一个栅格堆栈中提取了多年的最大温度值,针对我感兴趣的某些空间点。数据看起来类似于:

data <- cbind('1990' = c(25, 22, 35, 42, 44), '1991' = c(23, 28, 33, 40, 45), '1992' = c(20, 20, 30, 41, 43))

    1990   1991   1992
1     25     23     20
2     22     28     20
3     35     33     30
4     42     40     41
5     44     45     43

我希望得到每个地点高于30度的年数,例如:

    yr.above   
1          0
2          0
3          2
4          3
5          3

我已经尝试了一些方法,但它们都不起作用并且相当不合逻辑(例如,尝试length(data[1:length(data), which(blah blah无法理解),或使用apply(data,1,length(data)>30)。我知道这些没有意义,但我有点卡住了。

4个回答

40

这将为您提供所需的向量:

rowSums(data > 30)

无论data是矩阵还是数据框,此方法都适用。此外,它使用向量化函数,因此比使用apply(几乎等同于(缓慢的)for循环)更受欢迎。
如果data是数据框,您可以通过执行以下操作将结果添加为列:
data$yr.above <- rowSums(data > 30)

或者如果 data 是一个矩阵:
data <- cbind(data, yr.above = rowSums(data > 30))

你也可以创建一个全新的数据框:

data.frame(yr.above = rowSums(data > 30))

或一个全新的矩阵:

cbind(yr.above = rowSums(data > 30))

+1,但请注意,op示例中的“data”是一个“矩阵”,而不是一个“数据框”。 - thelatemail
谢谢。很难确定:cbind确实会给出一个矩阵,但问题中打印的数据表明是一个data.frame。我已经进行了编辑以解决这两种可能性。 - flodel
太好了!谢谢flodel。我特意没有看rowSums,因为我认为它会给我所有大于30的值的总和。事实上,我一直在使用rowSums来获取不同变量行的总和值... 活着就是学习。干杯! - Adam
2
非常欢迎。这个想法是data > 30返回一个由TRUE和FALSE组成的矩阵。当你在该矩阵上应用rowSums时,TRUE和FALSE分别被转换为1和0。 - flodel

6
apply的第三个参数需要是一个函数。此外,你可以使用sum函数计算逻辑真值的数量。
apply(data, 1, function(x)sum(x > 30))

2
另外,apply(data>30,1,sum) - Frank

3

我们还可以使用Reduce+(假设没有NA元素)

 Reduce(`+`, lapply(as.data.frame(data), `>`, 30))

我们不将其转换为矩阵,因此这应该是有效的。


3
使用 `dplyr` 包,您可以尝试以下两种解决方案。
library(dplyr)
df <- as.data.frame(data)

选项 1

df %>%
  mutate(yr.above = rowSums(across(`1990`:`1992`) > 30))

选项 2

dplyr 1.0.0 版本之后,您可以使用 c_across()rowwise() 结合使用,以便轻松执行 逐行 聚合操作。

df %>%
  rowwise() %>%
  mutate(yr.above = sum(c_across(`1990`:`1992`) > 30)) %>%
  ungroup()

注意: 使用dplyr的好处之一是支持整洁选择,它提供了一个简明的R方言来根据名称或属性选择变量。


输出

# # A tibble: 5 x 4
#   `1990` `1991` `1992` yr.above
#    <dbl>  <dbl>  <dbl>    <int>
# 1     25     23     20        0
# 2     22     28     20        0
# 3     35     33     30        2
# 4     42     40     41        3
# 5     44     45     43        3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接