尝试不使用merge()和使用union(),match()或%in%合并两个数据帧

时间:2019-06-22 15:59:47

标签: r

我想构造两个数据帧并合并它们,而不使用任何形式的merge()。相反,我需要使用set操作union()和match()或%in%运算符。以下输出必须显示d1,d2的内容​​以及d1和d2合并的结果。

我已经知道如何使用merge()来做到这一点,但是我无法找到如何使用union()和match()或%in%运算符来做到这一点。或其他任何方式。另外我的输出与输出应不匹配。我是初学者,感谢您的帮助。

d1.Kids <- c("Jack", "Jill", "Jillian", "John", "James")
d1.States <- c("CA", "MA", "DE", "HI", "PA")

d1 <- data.frame(d1.Kids, d1.States, stringsAsFactors = FALSE)

d2.Ages <- c(10, 7, 12, 30)
d2.Kids <- c("Jill", "Jillian", "Jack", "Mary")

d2 <- data.frame(d2.Ages, d2.Kids, stringsAsFactors = FALSE)

# Merging two created data frame
merge <- merge(d1, d2, by.x = "d1.Kids", by.y = "d2.Kids", all = TRUE)

print(merge)

Output should be:

  kids    ages states 
1 Jack    12   CA
2 Jill    10   MA
3 Jillian 7    DE
4 John    NA   HI
5 James   NA   PA
6 Mary    30   NA

3 个答案:

答案 0 :(得分:4)

像这样的事情会完成问题的要求。
似乎很长,但实际上对于要合并的每个数据帧来说,指令集都是相同的。

Kids <- union(d1$d1.Kids, d2$d2.Kids)

States <- rep(NA_character_, length(Kids))
Ages <- rep(NA_real_, length(Kids))

States[match(d1$d1.Kids, Kids)] <- as.character(d1$d1.States)
Ages[match(d2$d2.Kids, Kids)] <- d2$d2.Ages

mrg <- data.frame(Kids, States, Ages)

mrg
#     Kids States Ages
#1    Jack     CA   12
#2    Jill     MA   10
#3 Jillian     DE    7
#4    John     HI   NA
#5   James     PA   NA
#6    Mary   <NA>   30

答案 1 :(得分:1)

使用基数R:

kids <- unique(c(d1$Kids, d2$Kids))
d3 <- data.frame("Kids" = kids, "ages" = NA, "states" = NA)
for (i in seq_along(kids)) {
if (any(d2$Kids == kids[i])) {
d3[which(d3$Kids == kids[i]),]$ages <- d2[which(d2$Kids == kids[i]),]$ages
} 
if (any(d1$Kids == kids[i])) {
d3[which(d1$Kids == kids[i]),]$states <- d1[which(d2$Kids == kids[i]),]$states
}
}

答案 2 :(得分:1)

这是使用match和提取的另一种方式。

nm <- c("kids", "ages", "states")
s1 <- na.omit(match(d1$d1.Kids, d2$d2.Kids))
s2 <- na.omit(match(d2$d2.Kids, d1$d1.Kids))
r1 <- setNames(data.frame(d1[s1, ], d2[s2, 1]), nm)
res <- if (!setequal(d1$d1.Kids, d2$d2.Kids)) {
  r2 <- setNames(data.frame(d1[-s1, ], NA), nm)
  r3 <- setNames(data.frame(d2[-s2, 2], NA, d2[-s2, 1]), nm)
  rbind(r1, r2, r3)
} else {
  r1
}
res
#       kids ages states
# 1     Jack   CA     10
# 2     Jill   MA      7
# 3  Jillian   DE     12
# 4     John   HI     NA
# 5    James   PA     NA
# 11    Mary <NA>     30