您好我有两个数据框如下:
df1:
ID x y z
1 a b c
2 a b c
3 a b c
4 a b c
和df2:
ID x y
2 d NA
3 NA e
我正在追查这样的结果:
df1:
ID x y z
1 a b c
2 d b c
3 a e c
4 a b c
我一直在尝试使用其他帖子建议的匹配功能,但我一直遇到问题,我的df1数据帧被替换为来自df2的NA值。 这是我一直在使用的代码
for (i in names(df2)[2:length(names(df2))]) {
df1[i] <- df2[match(df1$ID, df2$ID)]
}
由于
答案 0 :(得分:0)
你的代码对我不起作用,所以我稍微改了一下但是有效。如果您正在阅读外部文件中的数据,请在阅读时使用stringAsFactor = FALSE
,这样您就不会遇到问题。
df1 = data.frame("ID" = 1:4,"x" = rep("a",4), "y" =rep("b",4),"z" = rep("c",4),
stringsAsFactors=FALSE)
df2 = data.frame("ID" = 2:3,"x" = c("d",NA), "y" = c(NA,"e"),stringsAsFactors=FALSE)
for(i in 1:nrow(df2)){
new_data = df2[i,-which(apply(df2[i,],2,is.na))]
pos = as.numeric(new_data[1])
col_replace = intersect(colnames(new_data),colnames(df1))
df1[pos,col_replace] = new_data
}
答案 1 :(得分:0)
使用dplyr
的解决方案。我们的想法是将两个数据帧转换为长格式,进行连接和替换值,并将格式转换回宽格式。 df5
是最终输出。
library(dplyr)
library(tidyr)
df3 <- df1 %>% gather(Col, Value, -ID)
df4 <- df2 %>% gather(Col, Value, -ID, na.rm = TRUE)
df5 <- df3 %>%
left_join(df4, by = c("ID", "Col")) %>%
mutate(Value.x = ifelse(!is.na(Value.y), Value.y, Value.x)) %>%
select(ID, Col, Value.x) %>%
spread(Col, Value.x)
df5
# ID x y z
# 1 1 a b c
# 2 2 d b c
# 3 3 a e c
# 4 4 a b c
数据强>
df1 <- read.table(text = "ID x y z
1 a b c
2 a b c
3 a b c
4 a b c",
header = TRUE, stringsAsFactors = FALSE)
df2 <- read.table(text = "ID x y
2 d NA
3 NA e",
header = TRUE, stringsAsFactors = FALSE)
答案 2 :(得分:0)
As mentioned by alistaire,这是更新联接。它与data.table
软件包一起提供:
library(data.table)
setDT(df1)
setDT(df2)
df1[df2, on = "ID", x := ifelse(is.na(i.x), x, i.x)]
df1[df2, on = "ID", y := ifelse(is.na(i.y), y, i.y)]
df1
ID x y z 1: 1 a b c 2: 2 d b c 3: 3 a e c 4: 4 a b c
如果有很多具有替换值的列,那么在将列名视为数据重整为长格式之后,可能值得跟随www's suggestion进行替换:
library(data.table)
melt(setDT(df1), "ID")[
melt(setDT(df2), "ID", na.rm = TRUE), on = .(ID, variable), value := i.value][
, dcast(.SD, ID ~ variable)]
ID x y z 1: 1 a b c 2: 2 d b c 3: 3 a e c 4: 4 a b c
df1 <- fread(
"ID x y z
1 a b c
2 a b c
3 a b c
4 a b c")
df2 <- fread(
"ID x y
2 d NA
3 NA e")