我想构造两个数据帧并在不使用任何形式的merge((的情况下合并它们。相反,我需要使用集合操作 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
这样的事情会做问题所要求的。
它看起来很长,但实际上它是要合并的每个数据帧的同一组指令。
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
使用基本 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
}
}
这是使用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