【问题标题】:count the number of columns for each row by condition on character and missing按字符和缺失条件计算每行的列数
【发布时间】:2020-05-23 08:32:46
【问题描述】:

我想按字符和缺失的条件计算每行的列数。

例如,我有这个数据集,test

我想创建num 列,计算缺失值或空值中“不”的列数。

a<-c("aa","bb","cc","dd","",NA)
b<-c("",NA,"aa","","","dd")
c<-c("aa","",NA,NA,"cc","dd")
d<-c("aa","bb","",NA,"cc","dd")
test<-data.frame(cbind(a,b,c,d))

     a    b    c    d
1   aa        aa   aa
2   bb <NA>        bb
3   cc   aa <NA>     
4   dd      <NA> <NA>
5             cc   cc
6 <NA>   dd   dd   dd

我想计算包含NA 和空值之类的列数

     a    b    c    d   num
1   aa        aa   aa   3
2   bb <NA>        bb   2
3   cc   aa <NA>        2
4   dd      <NA> <NA>   1
5             cc   cc   2
6 <NA>   dd   dd   dd   3

我在其他帖子中尝试了一些方法,例如rowSums

Count number of columns by a condition (>) for each row

> test$num<-rowSums(test!=c("",NA),na.rm=T)
> test
     a    b    c    d num
1   aa        aa   aa   3
2   bb <NA>        bb   0
3   cc   aa <NA>        2
4   dd      <NA> <NA>   0
5             cc   cc   2
6 <NA>   dd   dd   dd   0

但是,它返回错误的数字,我找不到原因。

你能告诉我如何解决这个问题吗?

【问题讨论】:

    标签: r count conditional-statements rowsum


    【解决方案1】:

    您可以使用nchar + rowSums

    test$num <- rowSums(nchar(as.matrix(test))>1,na.rm = TRUE)
    

    %in% + rowSums

    test$num <- rowSums(`dim<-`(!as.matrix(test) %in% c("",NA),dim(test)))
    

    这样

    > test
         a    b    c    d num
    1   aa        aa   aa   3
    2   bb <NA>        bb   2
    3   cc   aa <NA>        2
    4   dd      <NA> <NA>   1
    5             cc   cc   2
    6 <NA>   dd   dd   dd   3
    

    【讨论】:

      【解决方案2】:

      您可以使用rowSums 计算每行中NAs 的数量或空值,然后从数据框中的列数中减去它。

      test$num <- ncol(test) - rowSums(is.na(test) | test == "")
      test
      #     a    b    c    d num
      #1   aa        aa   aa   3
      #2   bb <NA>        bb   2
      #3   cc   aa <NA>        2
      #4   dd      <NA> <NA>   1
      #5             cc   cc   2
      #6 <NA>   dd   dd   dd   3
      

      【讨论】:

      • 删除了我的答案,因为它太接近你的答案:rowSums(test != "" &amp; !is.na(test))
      • @sindri_baldur 我认为这是一个不同的答案。
      【解决方案3】:

      使用rowSums 的另一个想法是将空替换为 NA,即

      rowSums(!is.na(replace(test, test == '', NA)))
      #[1] 3 2 2 1 2 3
      

      【讨论】:

        【解决方案4】:

        tidyverse 中的这种方法如何,它还告诉您有多少列包含 NA 或空字符串?

        a<-c("aa","bb","cc","dd","",NA)
        b<-c("",NA,"aa","","","dd")
        c<-c("aa","",NA,NA,"cc","dd")
        d<-c("aa","bb","",NA,"cc","dd")
        test<-data.frame(cbind(a,b,c,d))
        
        library(magrittr) #import the pipe operator
        
        num_cols <- test %>% 
            tibble::rowid_to_column("row_id") %>% #1st add a rowid column 
            dplyr::group_by(row_id) %>% #split the data into single row groups (i.e. 
                                        #row vectors)
            tidyr::nest() %>% #turn it into a list column called data
            dplyr::mutate(num_NAs = purrr::map_dbl(data, #loop over the data column of row 
                                                          #vectors using map_dbl
                                             ~sum(is.na(.))), #count the number of NAs
                          num_empty = purrr::map_dbl(data, 
                                                 #count the empty strings 
                                                 ~sum(. == "", na.rm = T)),
                          num_values = purrr::map_dbl(data, 
                                                  #count columns without NAs or 
                                                  #missing values (what you asked for)
                                                  ~length(.)-sum(num_NAs, num_empty))
                    ) %>%
            dplyr::ungroup() %>% #remove the grouping structure
            dplyr::select(num_NAs, num_empty, num_values) #extract only the variables you need
        
        test_v2 <- cbind(test, num_cols)
        test_v2  
        
             a    b    c    d num_NAs num_empty num_values
        1   aa        aa   aa       0         1          3
        2   bb <NA>        bb       1         1          2
        3   cc   aa <NA>            1         1          2
        4   dd      <NA> <NA>       2         1          1
        5             cc   cc       0         2          2
        6 <NA>   dd   dd   dd       1         0          3
        

        【讨论】:

        • 虽然此解决方案需要比其他选项更多的代码,但它会为您提供更多信息(如果您需要的话)。如果您不想获取整个数据帧的计数,您还可以轻松地在开头(group_by 层之前)插入一个 select() 层,以便仅将这些计数规则应用于列的子集。
        猜你喜欢
        • 1970-01-01
        • 2013-09-22
        • 1970-01-01
        • 2016-01-26
        • 2022-08-23
        • 2015-07-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多