当连接两个数据框时,如何用另一个数据集中的值替换一个数据集中的缺失值?
我的工作示例来自3波(时间点)研究,其中一些问题在连续波中被省略。 我想以长格式生成所有波的完整数据集,这样我就可以轻松拆分成较小的集合,同时保持 所有有意义的变量。
以下是一些可复制的代码:
df1<-data.frame(id=seq(10),
sex=rep(c(1,2), 5),
age=sample(c(18:24), 10, replace = T),
x = rnorm(10),
wave = rep("wave1", 10))
df2<-data.frame(id=seq(10),
x = rnorm(10),
wave = rep("wave2", 10))
dplyr::full_join(df1, df2)
Joining, by = c("id", "x", "wave")
id sex age x wave
1 1 1 18 0.7236847 wave1
2 2 2 18 0.5730599 wave1
3 3 1 21 2.0341799 wave1
4 4 2 20 -0.1531575 wave1
5 5 1 18 -0.6089901 wave1
6 6 2 18 -0.3233804 wave1
7 7 1 19 -0.1417807 wave1
8 8 2 21 0.9557512 wave1
9 9 1 24 0.6522168 wave1
10 10 2 20 0.1595824 wave1
11 1 NA NA 1.9694018 wave2
12 2 NA NA 1.4153806 wave2
13 3 NA NA 1.1160011 wave2
14 4 NA NA -0.6040353 wave2
15 5 NA NA -0.3750569 wave2
16 6 NA NA 0.4826182 wave2
17 7 NA NA 0.7210480 wave2
18 8 NA NA 1.9068413 wave2
19 9 NA NA 1.5355046 wave2
20 10 NA NA 1.3607414 wave2
我的目标是:基于参与者id
,用wave1数据替换wave2测量的sex
和age
中的NA。
编辑:请假设,我不再有权访问df1
和df2
-我仅使用联合数据,实际上还有更多``NA`s附带的变量。我应该早点指定这个。
答案 0 :(得分:2)
更新
如果没有访问df1和df2的权限,则可以使用zoo
的{{1}}函数
na.locf
答案 1 :(得分:1)
您实际上需要rbind
不合并,因此您可以创建两个额外的列和rbind
,即
rbind(df1, data.frame(df2, sex = df1$sex, age = df1$age))
给出,
id sex age x wave 1 1 1 24 0.23277867 wave1 2 2 2 19 0.28211730 wave1 3 3 1 23 0.69541360 wave1 4 4 2 21 0.11846487 wave1 5 5 1 23 -0.08540101 wave1 6 6 2 19 1.55917732 wave1 7 7 1 20 -0.27636738 wave1 8 8 2 20 -1.55094487 wave1 9 9 1 21 1.60901222 wave1 10 10 2 21 -0.05709374 wave1 11 1 1 24 -0.86825838 wave2 12 2 2 19 -0.32215557 wave2 13 3 1 23 -1.29894673 wave2 14 4 2 21 -0.24631532 wave2 15 5 1 23 2.65130947 wave2 16 6 2 19 0.03424642 wave2 17 7 1 20 0.55383179 wave2 18 8 2 20 0.09771911 wave2 19 9 1 21 -0.14435681 wave2 20 10 2 21 -1.66916275 wave2
答案 2 :(得分:1)
如果您想考虑加入后更改值,我们可以match
,然后更新值
df3 <- dplyr::full_join(df1, df2)
inds <- match(df3$id[df3$wave == "wave1"], df3$id[df3$wave == "wave2"])
df3[df3$wave == "wave2", c("sex", "age")] <- df3[inds, c("sex", "age")]
# id sex age x wave
#1 1 1 24 -0.76956510 wave1
#......
#......
#16 6 2 24 -0.25209124 wave2
#17 7 1 24 1.93524314 wave2
#18 8 2 21 0.02210736 wave2
#19 9 1 19 -1.03520607 wave2
#20 10 2 24 0.54103663 wave2
答案 3 :(得分:1)
您还可以使用dplyr
和zoo
包在三行中做到这一点。
library(dplyr)
library(zoo)
df3 <- dplyr::full_join(df1, df2)
df3 %>%
arrange(id) %>%
do(na.locf(.))
答案 4 :(得分:1)
您可以使用mutate_at
并为每个id
保留第一个值:
df3 %>%
group_by(id) %>%
mutate_at(vars(sex,age),first) %>%
ungroup()
# # A tibble: 20 x 5
# id sex age x wave
# <int> <dbl> <int> <dbl> <chr>
# 1 1 1 20 -1.9380810 wave1
# 2 2 2 18 -1.6587271 wave1
# 3 3 1 19 -0.3262624 wave1
# 4 4 2 22 1.7939726 wave1
# 5 5 1 24 -0.7964016 wave1
# 6 6 2 22 0.3781070 wave1
# 7 7 1 18 -0.5051593 wave1
# 8 8 2 20 -0.4301633 wave1
# 9 9 1 18 2.0959696 wave1
# 10 10 2 23 0.8634686 wave1
# 11 1 1 20 2.3539693 wave2
# 12 2 2 18 0.5544678 wave2
# 13 3 1 19 -0.1502509 wave2
# 14 4 2 22 1.0797118 wave2
# 15 5 1 24 0.3716175 wave2
# 16 6 2 22 1.1135225 wave2
# 17 7 1 18 0.5832351 wave2
# 18 8 2 20 0.8694125 wave2
# 19 9 1 18 -0.3765263 wave2
# 20 10 2 23 -0.4019392 wave2