我有一个巨大的数据框,有两列我需要结合起来。 On可能想知道这篇文章here中是否提到了同样的问题,但我的数据框实际上并没有这样做。仅存在两列。还有更多(很多NA' s),我只想处理其中的两个,这让我觉得它有点复杂。
这是这些专栏的一部分:
col1 col2
15 NA 4
16 NA 5
17 NA 5
18 NA 5
19 NA 1
20 NA NA
21 NA NA
22 1 NA
23 5 NA
24 2 NA
25 4 NA
26 3 NA
27 NA 2
28 NA 4
29 NA 5
30 NA 3
我需要通过替换彼此的NA来将列组合成一个。当两列都包含NA(但这很明显)时,不会发生预置位。
结果应如下所示:
col1
15 4
16 5
17 5
18 5
19 1
20 NA
21 NA
22 1
23 5
24 2
25 4
26 3
27 2
28 4
29 5
30 3
我尝试了一个丑陋的for循环:
for (i in 1:nrow(df)){
if (is.na(df[i,1])==TRUE){
df[i,1] <- df[i,2]
}
}
df <- df[,1]
但该代码似乎太慢了。有没有人知道两个人如何处理这个问题?
非常感谢提前!
答案 0 :(得分:3)
因为您可以分配到子集,所以不需要循环:
df$col1[is.na(df$col1)] <- df$col2[is.na(df$col1)]
答案 1 :(得分:1)
像SQL这样的语言有一个名为coalesce
的函数,它在给定一组列表的情况下返回第一个非缺失值。我写了一个在R中执行此行为的函数。
coalesce<-function(...) {
x<-lapply(list(...), function(z) {if (is.factor(z)) as.character(z) else z})
m<-is.na(x[[1]])
i<-2
while(any(m) & i<=length(x)) {
if ( length(x[[i]])==length(x[[1]])) {
x[[1]][m]<-x[[i]][m]
} else if (length(x[[i]])==1) {
x[[1]][m]<-x[[i]]
} else {
stop(paste("length mismatch in argument",i," - found:", length( x[[i]] ),"expected:",length( x[[1]] ) ))
}
m<-is.na(x[[1]])
i<-i+1
}
return(x[[1]])
}
你会像
一样使用它coalesce(col1,col2)
如果所有行都是NA
,您还可以添加默认值coalesce(col1,col2, -9)
它返回一个新列,而不是修改任何原件。
我尝试在this gist
上保留最新版本的功能