我想用我的数据框中的NA替换来自另一列的值。例如:
a1 <- c(1, 2, 4, NA, 2, NA)
b1 <- c(3, NA, 4, 4, 4, 3)
c1 <- c(NA, 3, 3, 4, 2, 3)
a2 <- c(2, 3, 5, 5, 3, 4)
b2 <- c(1, 2, 4, 5, 6, 3)
c2 <- c(3, 3, 2, 3, 4, 3)
df <- as.data.frame(cbind(a1, b1, c1, a2, b2, c2))
df
> df
a1 b1 c1 a2 b2 c2
1 1 3 NA 2 1 3
2 2 NA 3 3 2 3
3 4 4 3 5 4 2
4 NA 4 4 5 5 3
5 2 4 2 3 6 4
6 NA 3 3 4 3 3
我想将df$a1
中的NAs替换为df$a2
中相应行的值,df$b1
中的NAs以及df$b2
中相应行的值和df$c1
中的NA以及df$c2
中相应行的值,以便新数据框如下所示:
> df
a1 b1 c1
1 1 3 3
2 2 2 3
3 4 4 3
4 5 4 4
5 2 4 2
6 4 3 3
我该怎么做?我有一个包含许多列的大型数据框,因此找到一种有效的方法(我已经看过Replace missing values with a value from another column)会很棒。谢谢!
答案 0 :(得分:1)
可扩展选项:
df2 <- df[c('a1','b1','c1')]
df2[] <- mapply(function(x,y) ifelse(is.na(x), y, x),
df[c('a1','b1','c1')], df[c('a2','b2','c2')],
SIMPLIFY=FALSE)
df2
# a1 b1 c1
# 1 1 3 3
# 2 2 2 3
# 3 4 4 3
# 4 5 4 4
# 5 2 4 2
# 6 4 3 3
将此扩展到任意列对很容易:第一个子集中的第一列(df[c('a1','b1','c1')]
)与第二个子集的第一列配对;第二列第一子集,第二列第二子集;它甚至可以用df[grepl('1$',colnames(df))]
和df[grepl('2$',colnames(df))]
来概括,假设它们不匹配。
答案 1 :(得分:1)
coalesce
中的 dplyr
意味着要做到这一点(在第一个向量中替换NA而不是后一个向量的NA元素)。 e.g。
coalesce(df$a1,df$a2)
[1] 1 2 4 5 2 4
它可以与sapply一起使用,以高效且易于扩展的方式完成整个数据集:
sapply(c("a","b","c"),function(x) coalesce(df[,paste0(x,1)],df[,paste0(x,2)]))
a b c
[1,] 1 3 3
[2,] 2 2 3
[3,] 4 4 3
[4,] 5 4 4
[5,] 2 4 2
[6,] 4 3 3
答案 2 :(得分:0)
dfnew<- ifelse(is.na(df$a1) == T, df$a2, df$a1)
as.data.frame(dfnew)
这只是针对a1 col,你必须为所有a,b和c运行它并且cbind它。如果列太多,运行循环将是最好的选择imo
答案 3 :(得分:0)
您可以使用hutils::coalesce
。它应该稍快一点,特别是如果它可以“作弊” - 如果任何列没有NA
,所以不需要更改,coalesce
将跳过它们:
a1 <- c(1, 2, 4, NA, 2, NA)
b1 <- c(3, NA, 4, 4, 4, 3)
c1 <- c(NA, 3, 3, 4, 2, 3)
a2 <- c(2, 3, 5, 5, 3, 4)
b2 <- c(1, 2, 4, 5, 6, 3)
c2 <- c(3, 3, 2, 3, 4, 3)
s <- function(x) {
sample(x, size = 1e6, replace = TRUE)
}
df <- as.data.frame(cbind(a1 = s(a1), b1 = s(b1), c1 = s(c1),
a2 = s(a2), b2 = s(b2), c2 = s(c2)))
library(microbenchmark)
library(hutils)
library(data.table)
dt <- as.data.table(df)
old <- paste0(letters[1:3], "1") # you will need to specify
new <- paste0(letters[1:3], "2")
dplyr_coalesce <- function(df) {
ans <- df
for (j in seq_along(old)) {
o <- old[j]
n <- new[j]
ans[[o]] <- dplyr::coalesce(ans[[o]], df[[n]])
}
ans
}
hutils_coalesce <- function(df) {
ans <- df
for (j in seq_along(old)) {
o <- old[j]
n <- new[j]
ans[[o]] <- hutils::coalesce(ans[[o]], df[[n]])
}
ans
}
microbenchmark(dplyr = dplyr_coalesce(df),
hutils = hutils_coalesce(df))
#> Unit: milliseconds
#> expr min lq mean median uq max neval cld
#> dplyr 45.78123 61.76857 95.10870 69.21561 87.84774 1452.0800 100 b
#> hutils 36.48602 46.76336 63.46643 52.95736 64.53066 252.5608 100 a
由reprex package(v0.2.0)创建于2018-03-29。