【问题标题】:Count non-NA observations by row in selected columns在选定列中按行计算非 NA 观测值
【发布时间】:2020-12-10 18:51:17
【问题描述】:

我正在使用以下数据框:

Name  Color   L1    L2    R3 
Joe    Red    5.4   6.2   7.7
Eric   Blue   NA    4.1   6.1
Steve  Green  NA    NA    1.2
Mike   Red    NA    NA    NA

我想计算跨列 L1、L2 和 L3 的观察次数,但不计算 NA 值。所以我希望上表变成:

Name  Color   L1    L2    R3    Count 
Joe    Red    5.4   6.2   7.7    3
Eric   Blue   NA    4.1   6.1    2
Steve  Green  NA    NA    1.2    1
Mike   Red    NA    NA    NA     0

提前致谢!

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    我们可以在逻辑矩阵上使用rowSums,即is.na(df1[3:5])返回一个逻辑矩阵,其中TRUE -> NA和FALSE -> nonNA,通过否定(!)、TRUE -> FALSE,反之亦然。然后,使用rowSums,将 TRUE (TRUE/FALSE -> 1/0) 加在一起

    df1$Count <- rowSums(!is.na(df1[3:5]))
    

    或使用tidyverse

    library(dplyr)
    df1 %>%
        mutate(Count = rowSums(!is.na(select(., 3:5))))
    

    -输出

    #    Name Color  L1  L2  R3 Count
    #1   Joe   Red 5.4 6.2 7.7     3
    #2  Eric  Blue  NA 4.1 6.1     2
    #3 Steve Green  NA  NA 1.2     1
    #4  Mike   Red  NA  NA  NA     0
    

    或者如果我们需要在一个范围内使用列名,使用select

    df1 %>%
        mutate(Count = rowSums(!is.na(select(., L1:R3))))
     
    

    注意:rowSums 是矢量化的并且会非常快

    数据

    df1 <- structure(list(Name = c("Joe", "Eric", "Steve", "Mike"), Color = c("Red", 
    "Blue", "Green", "Red"), L1 = c(5.4, NA, NA, NA), L2 = c(6.2, 
    4.1, NA, NA), R3 = c(7.7, 6.1, 1.2, NA)), class = "data.frame",
    row.names = c(NA, 
    -4L))
    

    【讨论】:

    • 是否可以在 rowsums 命令中使用列名而不是列的位置?我只是认为如果这些列的位置发生变化会容易得多
    • @rogues77 你可以在select 中使用一系列列名,更新帖子
    • 非常感谢!我很惊讶您使用 rowSums() + dplyr 的第二个解决方案比 Duck 使用 rowwise() + c_across() 的以下答案快得多!
    • @elarry rowSums/rowMeansbase R 中一些最快的向量化函数,它们执行行明智的操作。而rowwise 是一个慢循环
    • 很高兴知道!由于它的可读性,我一直更喜欢 tidyverse 而不是 base R,但在这种情况下,rowSums() 是一个明显的胜利!非常感谢,@akrun!
    【解决方案2】:

    简单的基础 R 解决方案:

    df1$Count <- apply(df1[3:5], 1, function(x) sum(!is.na(x)))
    

    【讨论】:

      【解决方案3】:

      dplyr试试这个:

      library(dplyr)
      #Code
      newdf <- df %>% rowwise() %>% mutate(Count=sum(!is.na(c_across(L1:R3))))
      

      输出:

      # A tibble: 4 x 6
      # Rowwise: 
        Name  Color    L1    L2    R3 Count
        <chr> <chr> <dbl> <dbl> <dbl> <int>
      1 Joe   Red     5.4   6.2   7.7     3
      2 Eric  Blue   NA     4.1   6.1     2
      3 Steve Green  NA    NA     1.2     1
      4 Mike  Red    NA    NA    NA       0
      

      使用的一些数据:

      #Data
      df <- structure(list(Name = c("Joe", "Eric", "Steve", "Mike"), Color = c("Red", 
      "Blue", "Green", "Red"), L1 = c(5.4, NA, NA, NA), L2 = c(6.2, 
      4.1, NA, NA), R3 = c(7.7, 6.1, 1.2, NA)), class = "data.frame", row.names = c(NA, 
      -4L))
      

      【讨论】:

        猜你喜欢
        • 2022-11-08
        • 1970-01-01
        • 2017-11-01
        • 2017-06-10
        • 2022-12-20
        • 1970-01-01
        • 1970-01-01
        • 2022-07-15
        • 1970-01-01
        相关资源
        最近更新 更多