R 如何将丢失数据的数据框的两列组合起来?

R 如何将丢失数据的数据框的两列组合起来?,r,missing-data,R,Missing Data,这是一个扩展。如何将数据帧的两列合并为 data <- data.frame('a' = c('A','B','C','D','E'), 'x' = c("t",2,NA,NA,NA), 'y' = c(NA,NA,NA,4,"r")) 得到 'a' 'mycol' A t B 2 C NA D 4 E r 我试过这个 cbind(data[1]

这是一个扩展。如何将数据帧的两列合并为

data <- data.frame('a' = c('A','B','C','D','E'),
                   'x' = c("t",2,NA,NA,NA),
                   'y' = c(NA,NA,NA,4,"r"))
得到

 'a' 'mycol'  
  A   t  
  B   2  
  C   NA  
  D   4  
  E   r  
我试过这个

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

但是它显然不会保留
NA
行。

您可以使用
ifelse
这样做:

data$mycol <- ifelse(!is.na(data$x), data$x, data$y)

> data

##   a  x  y mycol
## 1 A  1 NA     1
## 2 B  2 NA     2
## 3 C NA NA    NA
## 4 D NA  4     4
## 5 E NA  5     5
data$mycl数据
##真菌
##1 A 1 NA 1
##2b2na2
##3c-NA-NA-NA
##4dNa4
##5 E NA 5 5

按照您的逻辑,您可以执行以下操作:

cbind(data[1], mycol = unlist(apply(data[2:3], 1, function(i) ifelse(
  length(is.na(i))==length(i),
  na.omit(i),
  NA)
)))

#  a mycol
#1 A     1
#2 B     2
#3 C    NA
#4 D     4
#5 E     5
这一点已经得到间接解决。以下是一个基于此的简单解决方案:

data$mycol <- coalesce(data$x, data$y)

data$mycl将答案扩展到任意数量的列,并使用整洁的
max.col()

coalesce <- function(value_matrix) {
  value_matrix <- as.matrix(value_matrix)
  first_non_missing <- max.col(!is.na(value_matrix), ties.method = "first")
  indices <- cbind(
    row = seq_len(nrow(value_matrix)),
    col = first_non_missing
  )
  value_matrix[indices]
}

data$mycol <- coalesce(data[, c('x', 'y')])
data
#   a  x  y mycol
# 1 A  1 NA     1
# 2 B  2 NA     2
# 3 C NA NA    NA
# 4 D NA  4     4
# 5 E NA  5     5

建议的重复:这种情况非常简单,您可以执行
pmin
pmax
,例如
data$mycol=pmin(data$x,data$y,na.rm=T)
。这将扩展到更多列,但如果有多个非缺失值,它将选择最小值。建议dupe处的合并答案将选择第一个非缺失值。其他相关Q用于像这里这样只有一个非
NA
列的简单情况;由@Henrik链接的聚结解决方案看起来是一个很好的一般情况。您也可以使用
data.table
来完成类似的任务,但您会失去NAs,转而使用0s<代码>setDT(数据);data[,new:=sum(.SD,na.rm=T),by=a,.SDcols=c(“x”,“y”])
继OP编辑两列字符串之后,它现在甚至更类似于我链接到的Q&a…在OP的情况下效果很好,但如果涉及更多列,则无法很好地扩展…与“是”相比有任何优势,它可以更好地扩展到更多列。添加比较以回答。。。
coalesce <- function(value_matrix) {
  value_matrix <- as.matrix(value_matrix)
  first_non_missing <- max.col(!is.na(value_matrix), ties.method = "first")
  indices <- cbind(
    row = seq_len(nrow(value_matrix)),
    col = first_non_missing
  )
  value_matrix[indices]
}

data$mycol <- coalesce(data[, c('x', 'y')])
data
#   a  x  y mycol
# 1 A  1 NA     1
# 2 B  2 NA     2
# 3 C NA NA    NA
# 4 D NA  4     4
# 5 E NA  5     5
coalesce_reduce <- function(...) {
  Reduce(function(x, y) {
    i <- which(is.na(x))
    x[i] <- y[i]
    x},
    list(...))
}

coalesce_maxcol <- function(...) {
  value_matrix <- cbind(...)
  first_non_missing <- max.col(!is.na(value_matrix), ties.method = "first")
  indices <- cbind(
    row = seq_len(nrow(value_matrix)),
    col = first_non_missing
  )
  value_matrix[indices]
}

set.seed(100)

wide <- replicate(
  1000,
  {sample(c(NA, 1:10), 10, replace = TRUE)},
  simplify = FALSE
)

long <- replicate(
  10,
  {sample(c(NA, 1:10), 1000, replace = TRUE)},
  simplify = FALSE
)

microbenchmark(
  do.call(coalesce_reduce, wide),
  do.call(coalesce_maxcol, wide),
  do.call(coalesce_reduce, long),
  do.call(coalesce_maxcol, long)
)
# Unit: microseconds
#                           expr      min        lq       mean   median       uq      max neval
# do.call(coalesce_reduce, wide) 1879.460 1953.5695 2136.09954 2007.303 2152.654 5284.583   100
# do.call(coalesce_maxcol, wide)  403.604  423.5280  490.40797  433.641  456.583 2543.580   100
# do.call(coalesce_reduce, long)   36.829   41.5085   45.75875   43.471   46.942   79.393   100
# do.call(coalesce_maxcol, long)   80.903   88.1475  175.79337   92.374  101.581 3438.329   100