【问题标题】:Count number of columns by a condition (>) for each row通过条件 (>) 计算每行的列数
【发布时间】:2013-09-22 14:46:29
【问题描述】:

我正在尝试为矩阵的每一行计算出有多少列的值大于指定值。很抱歉,我问了这个简单的问题,但我无法弄清楚。

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

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,长度(数据)> 30),我知道这些没有意义,但我有点卡住了。

【问题讨论】:

    标签: r count col


    【解决方案1】:

    这将为您提供您正在寻找的向量:

    rowSums(data > 30)
    

    data 是矩阵还是 data.frame 都可以。此外,它使用矢量化函数,因此是比使用 apply 更好的方法,apply 只不过是一个(慢)for 循环。

    如果data 是一个data.frame,您可以通过以下方式将结果添加为列:

    data$yr.above <- rowSums(data > 30)
    

    或者如果data 是一个矩阵:

    data <- cbind(data, yr.above = rowSums(data > 30))
    

    你也可以创建一个全新的data.frame:

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

    或一个全新的矩阵:

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

    【讨论】:

    • +1,但请注意操作示例中的 datamatrix 而不是 data.frame
    • 谢谢。很难说:cbind 确实给出了一个矩阵,但问题中的打印数据表明data.frame。我已经编辑以解决这两种可能性。
    • 完美!谢谢弗洛德尔。我故意不看 rowSums,因为我认为它会给我所有高于 30 的值的总和。事实上,我一直在使用 rowSums 来获取不同变量的行的总和值......生活和学习。干杯
    • 不客气。这个想法是data &gt; 30 返回一个 TRUE 和 FALSE 矩阵。当您在该矩阵上应用rowSums 时,TRUE 和 FALSE 将分别转换为 1 和 0。
    【解决方案2】:

    apply 的第三个参数需要是一个函数。此外,您可以使用 sum 计算逻辑真数。

    apply(data, 1, function(x)sum(x > 30))
    

    【讨论】:

    • 另外,apply(data&gt;30,1,sum)!
    【解决方案3】:

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

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

    这应该很有效,因为我们没有转换为matrix

    【讨论】:

      【解决方案4】:

      使用dplyr包,可以尝试以下两种解决方案。

      library(dplyr)
      df <- as.data.frame(data)
      

      选项 1

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

      选项 2

      dplyr 1.0.0 之后,您可以将c_across()rowwise() 一起使用,以便轻松执行row-wise聚合。

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-23
        • 2021-07-30
        • 1970-01-01
        • 1970-01-01
        • 2021-09-23
        • 1970-01-01
        相关资源
        最近更新 更多