使用dplyr计算左外连接结果的正确方法是什么?
考虑两个数据框:
a <- data.frame( id=c( 1, 2, 3, 4 ) )
b <- data.frame( id=c( 1, 1, 3, 3, 3, 4 ), ref_id=c( 'a', 'b', 'c', 'd', 'e', 'f' ) )
a
指定四种不同的ID。 b
指定了六个引用a
中ID的记录。如果我想查看引用每个ID的次数,我可以试试这个:
a %>% left_join( b, by='id' ) %>% group_by( id ) %>% summarise( refs=n() )
Source: local data frame [4 x 2]
id refs
(dbl) (int)
1 1 2
2 2 1
3 3 3
4 4 1
但是,结果具有误导性,因为它表明ID 2
曾被引用过一次,实际上它从未被引用(在中间数据框中,对于ID 2,ref_id为NA
)。我想避免引入单独的库,例如sqldf
。
答案 0 :(得分:3)
使用data.table,您可以
library(data.table)
setDT(a); setDT(b)
b[a, .N, on="id", by=.EACHI]
id N
1: 1 2
2: 2 0
3: 3 3
4: 4 1
此处,语法为x[i, j, on, by=.EACHI]
。
.EACHI
指的是i=a
的每一行。 j=.N
使用特殊变量作为行数。答案 1 :(得分:1)
已经有一些很好的答案,但由于问题不要在这里使用包是一个。我们在a
和b
上执行左连接,并附加refs
列,如果ref_id
不是NA,则该列为TRUE。然后使用aggregate
汇总refs
列:
m <- transform(merge(a, b, all.x = TRUE), refs = !is.na(ref_id))
aggregate(refs ~ id, m, sum)
,并提供:
id refs
1 1 2
2 2 0
3 3 3
4 4 1
答案 2 :(得分:0)
我很难决定这是一个黑客还是计算引用的正确方法,但这会返回预期的结果:
a %>% left_join( b, by='id' ) %>% group_by( id ) %>% summarise( refs=sum( !is.na( ref_id ) ) )
Source: local data frame [4 x 2]
id refs
(dbl) (int)
1 1 2
2 2 0
3 3 3
4 4 1