在full_join()之后,如何用另一个来源的数据替换一个来源中的NA

时间:2018-12-13 08:27:08

标签: r dataframe dplyr

当连接两个数据框时,如何用另一个数据集中的值替换一个数据集中的缺失值?

我的工作示例来自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测量的sexage中的NA。

编辑:请假设,我不再有权访问df1df2-我仅使用联合数据,实际上还有更多``NA`s附带的变量。我应该早点指定这个。

5 个答案:

答案 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)

您还可以使用dplyrzoo包在三行中做到这一点。

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