如何在R中按组匹配两列

时间:2014-11-13 16:22:40

标签: r

我有一个像d1这样的数据集。

d1<-structure(list(id = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 4L), cname = structure(c(1L, 
1L, 1L, 2L, 3L, 2L, 2L, 3L, 1L), .Label = c("AA", "BB", "CC"), class = "factor"), 
value = c(1L, 2L, 1L, 2L, 2L, 1L, 2L, 3L, 1L), recentcname = c(NA, 
NA, NA, NA, NA, NA, NA, NA, NA)), .Names = c("id", "cname", 
"value", "recentcname"), class = "data.frame", row.names = c(NA, 
-9L))

这里我的关键变量是&#34; id&#34;和&#34;价值&#34;。对于每个个人ID,我必须在&#34;值&#34;中找出最大值记录。列并取相应的&#34; cname&#34; string into&#34; recentcname&#34;该ID的列。如果我们有一个id的两个最大值,我们必须采取第二个最高记录&#34; cname&#34; string into&#34; recentcname&#34;列。

最后我的输出就像d2。

d2<-structure(list(id = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 4L), cname = structure(c(1L, 
1L, 1L, 2L, 3L, 2L, 2L, 3L, 1L), .Label = c("AA", "BB", "CC"), class = "factor"), 
value = c(1L, 2L, 1L, 2L, 2L, 1L, 2L, 3L, 1L), recentcname = structure(c(1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L), .Label = c("AA", "CC"), class = "factor")), .Names = c("id", 
"cname", "value", "recentcname"), class = "data.frame", row.names = c(NA, 
-9L))

我可以通过ib分割数据集来实现。但这是耗时的时间。这项任务还有其他选择吗?请帮忙......

2 个答案:

答案 0 :(得分:2)

这个怎么样

d1$recentcname <- unsplit(lapply(split(d1[,c("value","cname")], d1$id), function(x) {
    rep(tail(x$cname[x$value==max(x$value)],1), nrow(x))
}), d1$id)

我们基本上按ID分割数据,然后查找每个子集中的最后一个最大值,并为子集中的每一行重复该值。然后我们使用unsplit()但值返回的顺序与d1对应的正确顺序。

答案 1 :(得分:1)

尝试:

dd = do.call(rbind, lapply(split(d1, d1$id), function(x)tail(x,1)))
names(dd)[2]= 'recentcname'
merge(d1[1:3], dd[1:2])
  id cname value recentcname
1  1    AA     1          AA
2  1    AA     2          AA
3  1    AA     1          AA
4  2    BB     2          CC
5  2    CC     2          CC
6  3    BB     1          CC
7  3    BB     2          CC
8  3    CC     3          CC
9  4    AA     1          AA