如何在不知道列号的情况下将多个字符列合并为一列并删除NA

时间:2019-03-18 04:02:24

标签: r dplyr

我想创建一个包含其他没有NA字符的列。 我已经尝试过pastestr_cunite,但是无法获得预期的结果。也许我没有正确使用它们。

实际情况是,我无法预先知道列号,因为每个数据集可以根据年份而变化。

即有些数据集包含10年,但有些包含20年。

以下是输入数据:

input <- tibble(
  id = c('aa', 'ss', 'dd', 'qq'),
  '2017' = c('tv', NA, NA, 'web'),
  '2018' = c(NA, 'web', NA, NA),
  '2019' = c(NA, NA, 'book', 'tv')
)

# A tibble: 4 x 4
  id    `2017` `2018` `2019`
  <chr> <chr>  <chr>  <chr> 
1 aa    tv     NA     NA    
2 ss    NA     web    NA    
3 dd    NA     NA     book  
4 qq    web    NA     tv    

ALL列的期望输出是:

> output
# A tibble: 4 x 5
  id    `2017` `2018` `2019` ALL   
  <chr> <chr>  <chr>  <chr>  <chr> 
1 aa    tv     NA     NA     tv    
2 ss    NA     web    NA     web   
3 dd    NA     NA     book   book  
4 qq    web    NA     tv     web tv

感谢您的帮助!

4 个答案:

答案 0 :(得分:4)

这实际上是this问题的重复(或实际上是接近的),但things have changed since thenunite具有na.rm参数,该参数有助于删除NA

就列的选择而言,这里我们选择了所有列,而忽略了第一个而不指定列名,因此它应该适用于您使用多年的情况。

library(tidyverse)

input %>%
    unite("ALL", names(input)[-1], remove = FALSE, sep = " ", na.rm = TRUE)

# A tibble: 4 x 5
#  id    ALL    `2017` `2018` `2019`
#  <chr> <chr>  <chr>  <chr>  <chr> 
#1 aa    tv     tv     NA     NA    
#2 ss    web    NA     web    NA    
#3 dd    book   NA     NA     book  
#4 qq    web tv web    NA     tv    

在通过安装

安装了tidyr开发版之后,它对我有用
devtools::install_github("tidyverse/tidyr")

答案 1 :(得分:4)

这是一种base R方法

input$ALL <- apply(input[-1], 1, function(x) paste(na.omit(x), collapse=" "))
input$ALL
#[1] "tv"     "web"    "book"   "web tv"

答案 2 :(得分:1)

为了完整性(并补充LocoGris' data.table answer),还有三种其他方法可通过引用更新input ,即不复制整个数据对象。

所有方法都返回相同的结果,并且可以处理任意年数。

请注意,id应该是唯一键,即没有重复项。

整形,na.omit(),聚合

library(data.table)
setDT(input)[, ALL := melt(input, id.var = "id")[, toString(na.omit(value)), by = id]$V1][]
   id 2017 2018 2019     ALL
1: aa   tv <NA> <NA>      tv
2: ss <NA>  web <NA>     web
3: dd <NA> <NA> book    book
4: qq  web <NA>   tv web, tv

从宽格式到长格式重塑的BTW展示了一种更简洁的方式来存储稀疏填充的数据。

melt(input, id.var = "id", na.rm = TRUE)
   id variable value
1: aa     2017    tv
2: qq     2017   web
3: ss     2018   web
4: dd     2019  book
5: qq     2019    tv

重塑,聚合,加入

library(data.table)
setDT(input)[melt(input, id.var = "id", na.rm = TRUE)[, toString(value), by = id],
             on = "id", ALL := V1][]

这将从整形步骤的结果中删除NA的值,由于许多NA会使原始行顺序失真。因此,需要 update join

Filter(),聚合

library(data.table)
setDT(input)[, ALL := .SD[, toString(Filter(Negate(is.na), .SD)), by = id]$V1][]

答案 3 :(得分:0)

一种53.2k Followers, 11 Following, 1,396 Posts 5m Followers, 83 Following, 1.1m Posts # 53.2k; 11 ; 1,396 # 5m; 83 ; 1.1m 方法:

data.table