我搜索了各种连接问题,但似乎没有一个能完全回答这个问题。我有两个数据框,每个数据框都有一个 ID 列和几个信息列。
df1 <- data.frame(id = c(1:100), color = c(rep("blue", 25), rep("red", 25),
rep(NA, 25)), phase = c(rep("liquid", 50), rep("gas", 50)),
rand.col = rnorm(100))
df2 <- data.frame(id = c(51:100), color = rep("green", 50), phase = rep("gas", 50))
正如您所看到的,df1 缺少 df2 中存在的一些信息,而 df2 只是所有 id 的子集,但它们都有一些相似的列。有没有办法根据 DF2 中的匹配 ID 来填充 df1 中的缺失值?
我找到了一个类似的问题 https://stackoverflow.com/questions/34697032/fill-in-missing-values-nas-with-values-from-another-dataframe-in-r建议使用合并,但是当我尝试它时,它删除了两个数据帧中不存在的所有 id。另外,它需要手动删除重复的列,并且在我的真实数据集中,会有大量重复的列,这使得这样做很麻烦。即使忽略这一点,
推荐的解决方案:
df1 <- setNames(merge(df1, df2)[-2], names(df1))
and
df1[is.na(df1$color), "color"] <- df2[match(df1$id, df2$id), "color"][which(is.na(df1$color))]
不适合我,抛出各种错误。
我想到的另一种解决方案是使用rbind
然后丢弃不完整的案例。问题是,在我的真实数据集中,虽然有共享列,但也有非共享列,因此我必须创建共享列的中间对象,rbind
,然后丢弃不完整的情况,然后join
与原始对象一起重新获得删除的列。这似乎是不必要的迂回。
在这个例子中它看起来像
df2 = rbind(df1[,colnames(df2)], df2)
df2 = df2[complete.cases(df2),]
df2 = merge(df1[,c("id", "rand.col")], df2, by = "id")
并且,如果两个数据帧之间存在任何完全重复的行,我需要添加
df2 = unique(df2)
这个解决方案可以工作,但是很麻烦,并且随着匹配的列数的增加,情况会变得更糟。有更好的解决方案吗?
-编辑-修复了 Sathish 指出的示例数据中的问题
-edit2- 扩展示例数据
df1 = data.frame(id = c(1:100), wq2 = rnorm(50), wq3 = rnorm(50), wq4 = rnorm(50),
wq5 = rnorm(50))
df2 = data.frame(id = c(51:100), wq2 = rnorm(50), wq3 = rnorm(50), wq4 = rnorm(50),
wq5 = rnorm(50))
这些数据帧表示有许多列包含不完整数据,而第二个数据帧包含所有缺失数据的情况。理想情况下,我们不需要单独列出每个列wq1 := i.wq1
etc.