我有很多这样的变量:
Var1 Var2
"Asian" NA
NA "Black"
"White" NA
我想方便地将它们变成这种形式:
Race
"Asian"
"Black"
"White"
我一直在尝试这样的事情:
Race <- ifelse(is.na(Var1), Var2, Var1)
但是这会将值转换为级别的数字,并且数字不匹配(例如,产生1, 1, 2
)。有没有一种方便的方法(理想情况下使用简短的,不言自明的代码)? (您可以使用as.character
摆脱这种情况,但必须有更好的方法。)
答案 0 :(得分:4)
通过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"
答案 1 :(得分:2)
这个解决方案怎么样?:
ind <- apply(df, 1, function(x) which(!is.na(x)))
df[cbind(seq_along(ind), ind)]
[1] "Asian" "Black" "White"
答案 2 :(得分:1)
另一个解决方案(非常奇怪,我同意并且非常简短,你的列需要像你的例子中的字符一样):
> 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"