用列匹配的另一个数据集中的值替换一个数据集中的缺失值 (NA)
Replace missing values (NA) in one data set with values from another where columns match
我有一个包含 3 列的数据框 (datadf),'x'、'y 和 z。缺少几个 'x' 值 (NA
)。 'y' 和 'z' 是非测量变量。
x y z
153 a 1
163 b 1
NA d 1
123 a 2
145 e 2
NA c 2
NA b 1
199 a 2
我有另一个具有相同三列的数据框 (imputeddf):
x y z
123 a 1
145 a 2
124 b 1
168 b 2
123 c 1
176 c 2
184 d 1
101 d 2
我希望用 'imputeddf' 中的值替换 'x' in 'datadf' 中的 NA
,其中 'y' 和 'z' 两者匹配数据集('y' 和 'z' 的每个组合都有自己的值 'x' 需要填写)。
想要的结果:
x y z
153 a 1
163 b 1
184 d 1
123 a 2
145 e 2
176 c 2
124 b 1
199 a 2
我正在尝试这样的事情:
finaldf <- datadf
finaldf$x <- if(datadf[!is.na(datadf$x)]){ddply(datadf, x=imputeddf$x[datadf$y == imputeddf$y & datadf$z == imputeddf$z])}else{datadf$x}
但它不起作用。
使用我的估算值 df 填写 NA
的最佳方法是什么?
我会这样做:
library(data.table)
setDT(DF1); setDT(DF2)
DF1[DF2, x := ifelse(is.na(x), i.x, x), on=c("y","z")]
这给出了
x y z
1: 153 a 1
2: 163 b 1
3: 184 d 1
4: 123 a 2
5: 145 e 2
6: 176 c 2
7: 124 b 1
8: 199 a 2
评论。这种方法不是很好,因为它合并了 DF1
的 whole,而我们只需要合并 is.na(x)
的子集。在这里,改进看起来像(感谢@Arun):
DF1[is.na(x), x := DF2[.SD, x, on=c("y", "z")]]
这种方式类似于@RHertel 的回答。
来自@Jakob 的评论:
does this work for more than one x variable? If I want to fill up entire datasets with several columns?
您可以枚举所需的列:
DF1[DF2, `:=`(
x = ifelse(is.na(x), i.x, x),
w = ifelse(is.na(w), i.w, w)
), on=c("y","z")]
表达式可以使用 lapply
和 substitute
构造,可能,但是如果列集是固定的,那么像上面那样写出来可能是最干净的。
这是一个以 R 为基数的替代方案:
df1[is.na(df1$x),"x"] <- merge(df2,df1[is.na(df1$x),][,c("y","z")])$x
> df1
# x y z
#1 153 a 1
#2 163 b 1
#3 124 b 1
#4 123 a 2
#5 145 e 2
#6 176 c 2
#7 184 d 1
#8 199 a 2
一个dplyr
解决方案,在概念上与上述答案相同。要仅提取 imputeddf
中对应于 datadf
中的 NA 的行,请使用 semi_join
。然后,使用另一个连接匹配回 datadf
。 (不幸的是,这一步不是很干净。)
library(dplyr)
replacement_rows <- imputeddf %>%
semi_join(datadf %>% filter(is.na(x)), by = c("y", "z"))
datadf <- datadf %>%
left_join(replacement_rows, by = c("y", "z")) %>%
mutate(x = if_else(is.na(x.x), x.y, x.x)) %>%
select(x, y, z)
这就是你想要的:
> datadf
# A tibble: 8 x 3
x y z
<dbl> <chr> <dbl>
1 153 a 1
2 163 b 1
3 184 d 1
4 123 a 2
5 145 e 2
6 176 c 2
7 124 b 1
8 199 a 2
我有一个包含 3 列的数据框 (datadf),'x'、'y 和 z。缺少几个 'x' 值 (NA
)。 'y' 和 'z' 是非测量变量。
x y z
153 a 1
163 b 1
NA d 1
123 a 2
145 e 2
NA c 2
NA b 1
199 a 2
我有另一个具有相同三列的数据框 (imputeddf):
x y z
123 a 1
145 a 2
124 b 1
168 b 2
123 c 1
176 c 2
184 d 1
101 d 2
我希望用 'imputeddf' 中的值替换 'x' in 'datadf' 中的 NA
,其中 'y' 和 'z' 两者匹配数据集('y' 和 'z' 的每个组合都有自己的值 'x' 需要填写)。
想要的结果:
x y z
153 a 1
163 b 1
184 d 1
123 a 2
145 e 2
176 c 2
124 b 1
199 a 2
我正在尝试这样的事情:
finaldf <- datadf
finaldf$x <- if(datadf[!is.na(datadf$x)]){ddply(datadf, x=imputeddf$x[datadf$y == imputeddf$y & datadf$z == imputeddf$z])}else{datadf$x}
但它不起作用。
使用我的估算值 df 填写 NA
的最佳方法是什么?
我会这样做:
library(data.table)
setDT(DF1); setDT(DF2)
DF1[DF2, x := ifelse(is.na(x), i.x, x), on=c("y","z")]
这给出了
x y z
1: 153 a 1
2: 163 b 1
3: 184 d 1
4: 123 a 2
5: 145 e 2
6: 176 c 2
7: 124 b 1
8: 199 a 2
评论。这种方法不是很好,因为它合并了 DF1
的 whole,而我们只需要合并 is.na(x)
的子集。在这里,改进看起来像(感谢@Arun):
DF1[is.na(x), x := DF2[.SD, x, on=c("y", "z")]]
这种方式类似于@RHertel 的回答。
来自@Jakob 的评论:
does this work for more than one x variable? If I want to fill up entire datasets with several columns?
您可以枚举所需的列:
DF1[DF2, `:=`(
x = ifelse(is.na(x), i.x, x),
w = ifelse(is.na(w), i.w, w)
), on=c("y","z")]
表达式可以使用 lapply
和 substitute
构造,可能,但是如果列集是固定的,那么像上面那样写出来可能是最干净的。
这是一个以 R 为基数的替代方案:
df1[is.na(df1$x),"x"] <- merge(df2,df1[is.na(df1$x),][,c("y","z")])$x
> df1
# x y z
#1 153 a 1
#2 163 b 1
#3 124 b 1
#4 123 a 2
#5 145 e 2
#6 176 c 2
#7 184 d 1
#8 199 a 2
一个dplyr
解决方案,在概念上与上述答案相同。要仅提取 imputeddf
中对应于 datadf
中的 NA 的行,请使用 semi_join
。然后,使用另一个连接匹配回 datadf
。 (不幸的是,这一步不是很干净。)
library(dplyr)
replacement_rows <- imputeddf %>%
semi_join(datadf %>% filter(is.na(x)), by = c("y", "z"))
datadf <- datadf %>%
left_join(replacement_rows, by = c("y", "z")) %>%
mutate(x = if_else(is.na(x.x), x.y, x.x)) %>%
select(x, y, z)
这就是你想要的:
> datadf
# A tibble: 8 x 3
x y z
<dbl> <chr> <dbl>
1 153 a 1
2 163 b 1
3 184 d 1
4 123 a 2
5 145 e 2
6 176 c 2
7 124 b 1
8 199 a 2