【问题标题】:How to create new column with all non-NA values from multiple other columns?如何使用来自多个其他列的所有非 NA 值创建新列?
【发布时间】:2016-11-17 09:59:20
【问题描述】:

我想创建一个 d 列,其中包含来自其他列的所有非 NA 值。

我尝试了 ifelse,但无法弄清楚如何使其以正确的方式嵌套,以便将 c 列中的值也包含在内。 也许应该使用 ifelse 以外的其他东西?

这是一个“虚拟”数据框:

 a <- c(NA, NA, NA, "A", "B", "A", NA, NA)
 b <- c("D", "A", "C", NA, NA, NA, NA, NA)
 c <- c(NA, NA, NA, NA, NA, NA, "C", NA)
 data <- data.frame(a, b, c)

我希望 d 列看起来像这样:

 data$d <- c("D", "A", "C", "A", "B", "A", "C", NA)
 View(data)

【问题讨论】:

  • data[!is.na(data)]
  • 这会改变值的顺序。
  • 您需要保留所有 NA 的行吗? (即数据框的最后一行)
  • 是的。所有带有 NA 的行都应包含在 d 列中。并且值的顺序应该是完整的。
  • 你也可以试试data[cbind(1:nrow(data), max.col(!is.na(data)))]

标签: r if-statement dataframe conditional na


【解决方案1】:

我们可以使用pmax

do.call(pmax, c(data, list(na.rm=TRUE)))
#[1] "D" "A" "C" "A" "B" "A" "C" NA 

数据

data <- data.frame(a, b, c, stringsAsFactors=FALSE)

【讨论】:

    【解决方案2】:

    假设每一行只有一个非 NA 值,这是一个有点丑陋的想法,

    data$d <- apply(data, 1, function(i) ifelse(all(is.na(i)), NA, i[!is.na(i)]))
    data
    #     a    b    c    d
    #1 <NA>    D <NA>    D
    #2 <NA>    A <NA>    A
    #3 <NA>    C <NA>    C
    #4    A <NA> <NA>    A
    #5    B <NA> <NA>    B
    #6    A <NA> <NA>    A
    #7 <NA> <NA>    C    C
    #8 <NA> <NA> <NA> <NA>
    

    【讨论】:

    • 我目前无法对其进行测试,但我认为您可以只使用 na.omit 而不是整个匿名函数
    • 嗯...我认为它会删除所有带有 na 的行,但目前也无法对其进行测试
    • 我的意思是按行应用na.omit(使用apply)。如果我没记错的话,如果您尝试仅从 NA 中选择一个非 NA 值(但不是 100% 确定),您应该得到一个 NA
    • 啊,好吧...是的,这是有道理的...我会在早上测试它
    【解决方案3】:

    我也找到了这个解决方法,但我不确定我是否喜欢它:

    data <- as.matrix(data)
    data[is.na(data)] <- " "
    data <- data.frame(data)
    data$d <- with(data, paste0(a, b, c), na.rm=TRUE)
    View(data)
    

    【讨论】:

    • 这实际上不是一个坏方法。你比我早了几秒钟。您可以将其简化为 2 行:data[is.na(data)] &lt;- ""; data$d &lt;- with(data, paste0(a, b, c))
    • 谢谢。实际上事实证明,它将“空单元格”保存为一个空格,这在 d 列中给出了与行数一样多的因子级别:-(
    【解决方案4】:

    结果应该只是在“”而不是“”中出​​现在 NA 单元格中。

    如果空间无法避免,请在数据框列上使用 trimws 以在之后删除它们:

      data$d <- trimws(data$d)
    

    【讨论】:

      【解决方案5】:

      我很晚才处理类似的问题,并认为我会使用dplyrstringr 提供更通用的解决方案。

      library(tidyverse)
      a <- c(NA, NA, NA, "A", "B", "A", NA, NA)
      b <- c("D", "A", "C", NA, NA, NA, NA, NA)
      c <- c(NA, NA, NA, NA, NA, NA, "C", NA)
      data <- data.frame(a, b, c)
      
      data %>% 
        mutate_all(stringr::str_replace_na, replacement = "") %>% 
        mutate(d = stringr::str_c(a,b,c)) %>%
        mutate_all(stringr::str_replace, pattern = "^$", replacement = NA_character_)
      #>      a    b    c    d
      #> 1 <NA>    D <NA>    D
      #> 2 <NA>    A <NA>    A
      #> 3 <NA>    C <NA>    C
      #> 4    A <NA> <NA>    A
      #> 5    B <NA> <NA>    B
      #> 6    A <NA> <NA>    A
      #> 7 <NA> <NA>    C    C
      #> 8 <NA> <NA> <NA> <NA>
      

      reprex package (v0.2.1) 于 2019 年 5 月 6 日创建

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-07
        • 1970-01-01
        • 2021-05-12
        • 2021-06-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多