【问题标题】:R: two data frame mergeR:两个数据框合并
【发布时间】:2014-10-04 03:51:21
【问题描述】:

我想合并两个数据框,但是有一些行名重复。 如果两个数据框中的行名数不同,我希望它可以在少一列中显示“NA”。

我的例子:

test1 <- data.frame(name = c("A", "B", "C", "C", "C", "D"), n1 = c("15", "14", "13", "12", "11", "10"))
test2 <- data.frame(name = c("A", "B", "B", "C", "C", "D"), n1 = c("30", "31", "33", "39", "38", "40")) 

然后我按名称合并,我得到了

名称 n1.x n1.y

A   15   30 
B   14   31
B   14   33
C   13   39
C   13   38
C   12   39
C   12   38
C   11   39
C   11   38
D   10   40

它会重复 我想要的是

名称 n1.x n1.y

A   15   30 
B   14   31
B   NA   33
C   13   39
C   12   38
C   11   NA
D   10   40

我应该使用什么命令? 非常感谢!

【问题讨论】:

  • 非常未执行的行为,你能解释一下为什么你想要的输出只包含两个“B”行和三个“C”行吗?处理/思考步骤是什么?我猜你想要的东西太不寻常了,你必须对常规 merge(test1,test2,by="name") 的输出进行后处理...
  • @jaybee,这种情况发生在我的实验中,在相同情况下有超过 1 次观察。当然这是不寻常的,但我必须保留它们。

标签: r matrix merge


【解决方案1】:

试试:

test1$indx <- with(test1, ave(1:nrow(test1), name, FUN=seq_along))
test2$indx <- with(test2, ave(1:nrow(test2), name, FUN=seq_along))
merge(test1, test2, by=c("name","indx"),all=T)[,-2]
 #   name n1.x n1.y
# 1    A   15   30
# 2    B   14   31
# 3    B <NA>   33
# 4    C   13   39
# 5    C   12   38
# 6    C   11 <NA>
# 7    D   10   40

【讨论】:

  • 好把戏,我必须记住。 n1.xn1.y 是因素 - 除了as.numeric(as.character()),还有其他方法可以在您的方法中处理这个问题吗?
  • @Roman Lustrik,谢谢。 n1 中的 test1test2 都是因素。如果它们都作为因素开始,我不知道为什么应该将其更改为数字。要将其更改为数字,as.numeric(as.character()) 将是要走的路线。
  • 做得很好。不过,不需要by.xby.y。只需 by 一次即可,因为您重复了相同的变量名。
  • 谢谢你们!真的很有帮助。
【解决方案2】:

我会在 data.table.people 提供一个灵活、可扩展且快速的解决方案之前发布此内容。

请注意,这适用于提供的数据集。您应该仔细检查生产代码的结果。

下面的代码所做的是将共同级别的值粘在一起。剩下的只是记账。

ml <- vector("list", length(unique(test1$name)))
names(ml) <- unique(test1$name)

for (i in unique(test1$name)) {
  o1 <- test1[test1$name %in% i, , drop = FALSE]
  o2 <- test2[test2$name %in% i, , drop = FALSE]
  o.max <- max(c(nrow(o1), nrow(o2)))
  nc <- ifelse(o.max == 1, 2, o.max*2)
  out <- matrix(rep(NA, times = nc), nrow = nc/2)
  out[1:nrow(o1), 1] <- as.numeric(as.character(o1$n1))
  out[1:nrow(o2), 2] <- as.numeric(as.character(o2$n1))

  ml[[i]] <- out
}

count.each <- sapply(ml, nrow)
result <- do.call("rbind", ml)
colnames(result) <- c("n1.x", "n1.y")
data.frame(name = rep(names(ml), count.each), result)

  name n1.x n1.y
1    A   15   30
2    B   14   31
3    B   NA   33
4    C   13   39
5    C   12   38
6    C   11   NA
7    D   10   40

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多