【问题标题】:Paste together columns but ignore NAs将列粘贴在一起但忽略 NA
【发布时间】:2022-01-18 21:26:17
【问题描述】:

我想将多个列粘贴在一起,但忽略 NA。

这是一个基本的工作示例,说明 df 的外观以及我希望它的外观。有人有什么建议吗?

df <- data.frame("col1" = c("A", NA, "B", "C"),
                 "col2" = c(NA, NA, NA, "E"),
                 "col3" = c(NA, "D", NA, NA),
                 "col4" = c(NA, NA, NA, NA))

df_fixed <- data.frame("col" = c("A", "D", "B", "C,E"))

【问题讨论】:

    标签: r dataframe paste


    【解决方案1】:

    使用paste

    data.frame(col1=sapply(apply(df, 1, \(x) x[!is.na(x)]), paste, collapse=','))
    #   col1
    # 1    A
    # 2    D
    # 3    B
    # 4  C,E
    

    或者没有apply:

    data.frame(col1=unname(as.list(as.data.frame(t(df))) |>
                 (\(x) sapply(x, \(x) paste(x[!is.na(x)], collapse=',')))()))
    #   col1
    # 1    A
    # 2    D
    # 3    B
    # 4  C,E
    

    要添加为列,请使用transform

    transform(df, colX=sapply(apply(df, 1, \(x) x[!is.na(x)]), paste, collapse=','))
    #   col1 col2 col3 col4 colX
    # 1    A <NA> <NA>   NA    A
    # 2 <NA> <NA>    D   NA    D
    # 3    B <NA> <NA>   NA    B
    # 4    C    E <NA>   NA  C,E
    

    注意:其实你也可以用na.omit替换\(x) x[!is.na(x)],因为它的属性消失了;参见例如@G. Grothendieckanswer

    【讨论】:

    • 谢谢!如果我想将其保存为 df 中的新列,语法是什么?以下返回 df$col1.col1 df$col1
    • @user9974638 使用transform,请参阅更新。
    • 完美,谢谢!!
    【解决方案2】:

    我们可以使用unite,它可以有na.rm作为参数

    library(tidyr)
    library(dplyr)
    df %>% 
       unite(col, everything(), na.rm = TRUE, sep=",")
    

    -输出

      col
    1   A
    2   D
    3   B
    4 C,E
    

    或将base Rdo.calltrimws 一起使用

    data.frame(col = trimws(do.call(paste, c(df, sep = ",")),
          whitespace = "(?:,?NA,?)+"))
    

    -输出

      col
    1   A
    2   D
    3   B
    4 C,E
    

    【讨论】:

      【解决方案3】:

      使用 na.omit 和 toString。不使用任何包。

      data.frame(col = apply(df, 1, function(x) toString(na.omit(x)))
      ##    col
      ## 1    A
      ## 2    D
      ## 3    B
      ## 4 C, E
      

      如果输出中的空格有问题,请使用其中之一而不是显示的匿名函数:

      function(x) paste(na.omit(x), collapse = ",") 
      function(x) gsub(", ", ",", toString(na.omit(x)))
      

      【讨论】:

      • 考虑到这一点,但逗号后面有一个空格,与预期结果不同。
      • 不清楚这是否真的很重要,但我添加了一些替代方案以防万一。
      【解决方案4】:

      一个可能的基础 R 解决方案:

      df2 <- data.frame(col=apply(df,1, function(x) paste0(na.omit(x), collapse = ",")))
      
      df2
      
      #>   col
      #> 1   A
      #> 2   D
      #> 3   B
      #> 4 C,E
      

      【讨论】:

        猜你喜欢
        • 2021-04-20
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        • 2013-01-12
        • 1970-01-01
        • 2016-04-20
        • 2017-01-01
        相关资源
        最近更新 更多