R 将具有NAs的相似长度向量列表合并为一个向量

R 将具有NAs的相似长度向量列表合并为一个向量,r,R,这可能是重复的,但我似乎无法找到类似的问题。我有一个长度相似的(很长的)向量列表。每个向量元素包含一个字符。有时,多个向量在同一位置包含字符(从开始按顺序编号)。有时不包含字符(即全部包含NA)。可能有10个这样的向量,每个向量都有数百万个元素的长度。我需要找到一种快速且内存高效的方法将向量组合到单个向量,最好不使用任何依赖项(即无数据表或dplyr)。为了理解这个概念,这个例子既简单又简短 我有: x <- list(A = c(rep("A", 5), rep(NA

这可能是重复的,但我似乎无法找到类似的问题。我有一个长度相似的(很长的)向量列表。每个向量元素包含一个字符。有时,多个向量在同一位置包含字符(从开始按顺序编号)。有时不包含字符(即全部包含NA)。可能有10个这样的向量,每个向量都有数百万个元素的长度。我需要找到一种快速且内存高效的方法将向量组合到单个向量,最好不使用任何依赖项(即无数据表或dplyr)。为了理解这个概念,这个例子既简单又简短

我有:

x <- list(A = c(rep("A", 5), rep(NA, 5)), B = c(rep(NA, 4), rep("B", 5), NA))
谢谢你的帮助。我应该知道怎么做,但不知怎的,我忘了。我确实有一个应用解决方案,一行一行地进行,但效率很低。需要对解决方案进行矢量化

apply(do.call(cbind, x), 1, function(k) {
  if(sum(is.na(k)) == length(k)) {
    "none"
  } else if (sum(!is.na(k)) == 1) {
    k[!is.na(k)]
  } else {
    "conflict"
  }
})

此解决方案使用向量化函数
f
Reduce
将其应用于列表。但它假设所有向量都具有相同的长度。而
Reduce
的速度性能并不为人所知

f <- function(x, y){
  na.x <- is.na(x) | x == "none"
  na.y <- is.na(y) | y == "none"
  x[na.x & na.y] <- "none"
  x[!na.x & !na.y & x != y] <- "conflict"
  x[!na.x & na.y] <- x[!na.x & na.y]
  x[na.x & !na.y] <- y[na.x & !na.y]
  x
}

Reduce(f, x)
# [1] "A"        "A"        "A"        "A"        "conflict" "B"       
# [7] "B"        "B"        "B"        "none"    
Reduce(f, list(A=NA, B = NA, C = 'A'))
#[1] "A"

f以下是代码的矢量化版本:

dat <- do.call(cbind, x)
#Logical matrix
mat <- !is.na(dat)
#Number of non-NA's in each row
rs <- rowSums(mat)
#First non-NA value
val <- dat[cbind(1:nrow(dat), max.col(mat, ties.method = 'first'))]
#More than 1 non-NA value
val[rs > 1] <- 'conflict'
#Only NA value
val[rs == 0] <- 'none'
val

#[1] "A"        "A"        "A"        "A"        "Conflict" "B"       
#[7] "B"        "B"        "B"        "none"  
dat另一个

x <- list(A = c(rep("A", 5), rep(NA, 5)), B = c(rep(NA, 4), rep("B", 5), NA))
y <- apply(do.call('rbind', x), 2, function(x) toString(na.omit(x)))
y[!nzchar(y)] <- 'none'
replace(y, grepl(',', y), 'conflict')
# [1] "A"        "A"        "A"        "A"        "conflict" "B"        "B"        "B"        "B"        "none"

x谢谢大家的回复。我使用一个相对较小的数据集,大约700k个元素和6个向量,尝试了各种选择。我的应用解决方案耗时约2秒,Ronaksah的矢量化解决方案耗时0.3秒,@rawr解决方案耗时9秒。因此,此解决方案比我以前使用的应用方案快6-7倍。接受:)出于某种原因,我认为用
来定义“mat”更直观!is.na
。然后,我们可以在“val”中执行两个替换,而不是两个
ifelse
:多个非
NA
值:
val[rs>1]=“conflict”
;无非
NA
值:
val[rs==0]=“无”
。是的,这也应该更快。谢谢,更新了答案。@mt1022错误已纠正,谢谢你指出它。
x <- list(A = c(rep("A", 5), rep(NA, 5)), B = c(rep(NA, 4), rep("B", 5), NA))
y <- apply(do.call('rbind', x), 2, function(x) toString(na.omit(x)))
y[!nzchar(y)] <- 'none'
replace(y, grepl(',', y), 'conflict')
# [1] "A"        "A"        "A"        "A"        "conflict" "B"        "B"        "B"        "B"        "none"