如何最好地将具有 NA 的两个因素合并为一个变量

How best to collapse two factors with NAs into one variable

我有很多这样的变量集:

   Var1    Var2
"Asian"      NA
     NA  "Black"
"White"      NA

我想方便地把它们写成这种形式:

   Race
"Asian"
"Black"
"White"

我一直在尝试类似的方法:

Race <- ifelse(is.na(Var1), Var2, Var1)

但这会将值转换为级别的数字,并且数字不匹配(例如,产生 1, 1, 2)。有没有一种方便的方法来做到这一点(最好使用简短的、不言自明的代码)? (你可以用 as.character 摆脱这个,但必须有更好的方法。)

这个解决方案怎么样?:

ind <- apply(df, 1, function(x) which(!is.na(x)))
df[cbind(seq_along(ind), ind)]
[1] "Asian" "Black" "White"

通过 as.character 进行中间转换:
假设这是您的数据:

dat <- data.frame(Var1=c("Asian",NA,"White"),Var2=c(NA,"Black",NA))

do.call(pmax,c(lapply(dat,as.character),na.rm=TRUE))
#[1] "Asian" "Black" "White"

如果您需要处理特定的子集,您可以这样做:

do.call(pmax,c(lapply(dat[c("Var1","Var2")],as.character),na.rm=TRUE))

不需要 as.character 的替代方案是:

dat[cbind(1:nrow(dat),max.col(!is.na(dat)))]
#[1] "Asian" "Black" "White"

另一个解决方案(我同意这很奇怪而且很短,您的列需要像您的示例中那样具有特征):

> library(tidyr)
> unite(replace(df, is.na(df), ""), V, c(Var1, Var2), sep=''))$V
#[1] "Asian" "Black" "White"

或者,使用 gsub 可能有风险,但这里 NA 是字符链的一部分,所以很安全:

> gsub("NA", "", unite(df, V, c(Var1, Var2), sep='')$V)
#[1] "Asian" "Black" "White"