合并列以删除NA

use*_*199 35 merge r na

我在R中有一些列,每行只有一个值,其余的将是NA的.我想将这些组合成一个具有非NA值的列.有谁知道这样做的简单方法.例如,我可以如下:

data <- data.frame('a' = c('A','B','C','D','E'),
                   'x' = c(1,2,NA,NA,NA),
                   'y' = c(NA,NA,3,NA,NA),
                   'z' = c(NA,NA,NA,4,5))
Run Code Online (Sandbox Code Playgroud)

所以我会的

'a' 'x' 'y' 'z'  
 A   1   NA  NA  
 B   2   NA  NA  
 C  NA   3   NA  
 D  NA   NA  4  
 E  NA   NA  5
Run Code Online (Sandbox Code Playgroud)

而且我会得到

 'a' 'mycol'  
  A   1  
  B   2  
  C   3  
  D   4  
  E   5  
Run Code Online (Sandbox Code Playgroud)

包含NA的列的名称根据查询中较早的代码而更改,因此我将无法显式调用列名,但是我将包含NA的列的列名称存储为向量,例如,在此示例中cols <- c('x','y','z'),所以可以调用列data[, cols].

任何帮助,将不胜感激.

谢谢

MKR*_*MKR 25

一个dplyr::coalesce基础的解决方案可能是因为:

data %>% mutate(mycol = coalesce(x,y,z)) %>%
         select(a, mycol)
#   a mycol
# 1 A     1
# 2 B     2
# 3 C     3
# 4 D     4
# 5 E     5 
Run Code Online (Sandbox Code Playgroud)

数据

data <- data.frame('a' = c('A','B','C','D','E'),
                 'x' = c(1,2,NA,NA,NA),
                 'y' = c(NA,NA,3,NA,NA),
                 'z' = c(NA,NA,NA,4,5))
Run Code Online (Sandbox Code Playgroud)


Sve*_*ein 18

您可以使用unlist将列转换为一个向量.之后,na.omit可以用来删除NAs.

cbind(data[1], mycol = na.omit(unlist(data[-1])))

   a mycol
x1 A     1
x2 B     2
y3 C     3
z4 D     4
z5 E     5
Run Code Online (Sandbox Code Playgroud)

  • 这应该处理@julia 提出的问题:`cbind.data.frame(data[1], mycol=c(na.omit(c(t(data[, -1])))))` (2认同)

Jon*_*løv 12

这是一个更通用(但更简单)的解决方案,它扩展到具有无序NA的所有列类型(因子,字符等).该策略只是使用is.na索引将其他列的非NA值合并到合并列中:

data$m = data$x  # your new merged column start with x
data$m[!is.na(data$y)] = data$y[!is.na(data$y)]  # merge with y
data$m[!is.na(data$z)] = data$z[!is.na(data$z)]  # merge with z

> data
  a  x  y  z m
1 A  1 NA NA 1
2 B  2 NA NA 2
3 C NA  3 NA 3
4 D NA NA  4 4
5 E NA NA  5 5
Run Code Online (Sandbox Code Playgroud)

请注意,m如果同一行中有多个非NA值,则会覆盖现有值.如果你有很多列,你可以通过循环自动化colnames(data).


Rei*_*son 11

我会用rowSums()这个na.rm = TRUE论点:

cbind.data.frame(a=data$a, mycol = rowSums(data[, -1], na.rm = TRUE))
Run Code Online (Sandbox Code Playgroud)

这使:

> cbind.data.frame(a=data$a, mycol = rowSums(data[, -1], na.rm = TRUE))
  a mycol
1 A     1
2 B     2
3 C     3
4 D     4
5 E     5
Run Code Online (Sandbox Code Playgroud)

你必须直接调用方法(cbind.data.frame),因为上面的第一个参数不是数据框.

  • 好的解决方案 但是角色数据怎么样? (4认同)

jub*_*uba 5

像这样的东西?

data.frame(a=data$a, mycol=apply(data[,-1],1,sum,na.rm=TRUE))
Run Code Online (Sandbox Code Playgroud)

给出:

  a mycol
1 A     1
2 B     2
3 C     3
4 D     4
5 E     5
Run Code Online (Sandbox Code Playgroud)