【问题标题】:Removing cells from rows with NA从具有 NA 的行中删除单元格
【发布时间】:2021-10-16 11:43:09
【问题描述】:

我有以下数据(列数可变)

> df1<-data.frame(F1=c(1,5,"NA",9),F2=c(2,5,"a","NA"),F3=c(1,"NA","o","NA"))
> df1
  F1 F2 F3
1  1 2  1
2  5  5 NA
3 NA  a  o
4  9 NA NA

我想从行中删除 NA 单元格,并将列缩小到其中包含信息的单元格。

> df2
  F1  F2  F3
1  1  2   1
2  5  5 
3  a  o
4  9 

谢谢!

【问题讨论】:

    标签: r dataframe na


    【解决方案1】:

    我们可以试试下面的代码

    df1[] <- t(apply(
      df1,
      1,
      function(v) {
        v[order(v == "NA")]
      }
    ))
    

    给了

    > df1
      F1 F2 F3
    1  1  2  1
    2  5  5 NA
    3  a  o NA
    4  9 NA NA
    

    【讨论】:

    • 非常好!请您解释一下[ ]的申请?例如 df1[ ] 实际上是什么。
    • @AnoushiravanR [] 保留df1 的属性。在这种情况下,生成的矩阵被嵌入到df1“框架”中。
    • 技术很棒!谢谢你亲爱的托马斯的解释。
    【解决方案2】:

    根据您的偏好,我选择在省略"NA" 值之后完成每一行,"" 作为一种空白值。但你可以选择用真正的NA 值填充它们:

    library(dplyr)
    library(purrr)
    
    df1 %>%
      pmap_dfr(~ {x <- c(...)[c(...) != "NA"]
      setNames(c(x, rep("", ncol(df1) - length(x))), 
               names(df1))})
    
    # A tibble: 4 x 3
      F1    F2    F3   
      <chr> <chr> <chr>
    1 1     "2"   "1"  
    2 5     "5"   ""   
    3 a     "o"   ""   
    4 9     ""    ""   
    

    【讨论】:

      【解决方案3】:

      首先,您可以使用此功能将所有非NA单元格向左移动:

      df1 <- data.frame(F1=c(1,5,NA,9),F2=c(2,5,"a",NA),F3=c(1,NA,"o",NA))
      df1 <- as.data.frame(t(apply(df1,1, function(x) { return(c(x[!is.na(x)],x[is.na(x)]) )} )))
      colnames(df1) <- c("F1", "F2", "F3")
      

      输出:

      > print(df1)
        F1   F2   F3
      1  1    2    1
      2  5    5 <NA>
      3  a    o <NA>
      4  9 <NA> <NA>
      

      其次,为了应用空白单元格而不是 NA 观察,您可以尝试:

      df1 <- sapply(df1, as.character)
      df1[is.na(df1)] <- " "
      df1 <- as.data.frame(df1)
      

      输出:

      > print(df1)
        F1 F2 F3
      1  1  2  1
      2  5  5   
      3  a  o   
      4  9    
      

      注意:我将您的字符串“NA”更改为简单的 NA,以便更好地检测观察结果。我不确定您是否真的希望将 NA 值作为字符串观察。

      【讨论】:

        【解决方案4】:

        首先将您的数据框转换为字符(否则,如果您同时拥有数字和字符,这将是一个问题),然后应用行,移动值,用 NA 填充

        df2=sapply(df1,as.character)
        
        t(
          sapply(1:nrow(df1),function(i){
            tmp=df1[i,df1[i,]!="NA"]
            if (length(tmp)<ncol(df1)) {
              tmp=c(tmp,rep("NA",ncol(df1)-length(tmp)))
            }
            tmp
          })
        )
        
             F1  F2   F3  
        [1,] "1" "2"  "1" 
        [2,] "5" "5"  "NA"  
        [3,] "a" "o"  "NA"  
        [4,] "9" "NA" "NA"
        

        【讨论】:

          猜你喜欢
          • 2018-01-04
          • 2021-11-18
          • 2022-06-13
          • 1970-01-01
          • 2022-01-11
          • 2021-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多