使用dplyr从另一个数据框中提取数据?

5

我有一个数据框叫做dat_new,实际上它是临床就诊数据,hrn是患者ID,dov是访问日期(每个人多次访问)。然后,我有一个名为event的数据框,其中包含有日期的住院记录(每个人多次入院)。

我想做的是,对于每个诊所访问,我想要求出在该诊所访问之前发生的住院记录总和,很简单。

这可以使用plyr中的ddply完成,需要一些时间但运行良好。

temp <- ddply(dat_new, .(hrn,dov), summarise,
              dka2 = sum(event$event_code[which(event$hrn==hrn & event$doa <= dov)]==2),
              dka3 = sum(event$event_code[which(event$hrn==hrn & event$doa <= dov)]==3),
              dka8 = sum(event$event_code[which(event$hrn==hrn & event$doa <= dov)]==8)
)

现在,我试图用dplyr重写代码,但是出现了错误。

Error: binding not found: 'event_code'

我将其编码如下:

我已将其编码如下:

temp2 <- group_by(dat_new, hrn, dov)
temp3 <- summarise(temp2,
                   dka2 = sum(event$event_code[which(event$hrn==hrn & event$doa <= dov)]==2))

显然,event_code不在temp2数据框中。这是dplyr无法在“总结”时处理“其他”数据框的情况吗?如果有更好的方法来执行我正在进行的“查找/总和”,我会认真听取建议。
我试过几次,在vanilla R中以不同的顺序加载软件包,以尝试消除任何命名空间问题。
谢谢。
编辑-可重现的例子
这是一个简单而粗略的示例,仅用于说明问题。如果我们创建一个'lookup'数据框,其中每辆车都有两个mpg约为500,然后尝试查看原始数据框,在新数据框中查找并将两个mpg相加。 plyr给出了预期的答案,大约为1000。而dplyr则出现错误。
# add the model names as a column so they're easier to get at
mtcars$models <- row.names(mtcars)

# create a 'lookup' table
xtra <- data.frame(models = rep(row.names(mtcars),2),
                    newmpg = rnorm(2*nrow(mtcars),500,10)
)
xtra <- xtra[sample(row.names(xtra)), ]

library(plyr)
ddply(mtcars, .(models), summarise,
        revisedmpg = sum(xtra$newmpg[models==xtra$models]) )
# great, one row per car, with both mpgs added together
library(dplyr)

temp2 <- group_by(mtcars, models)
temp3 <- summarise(temp2,
                   revisedmpg = xtra$newmpg[models==xtra$models] )
# error

1
我几周前遇到了类似的问题,我认为这与 https://github.com/hadley/dplyr/issues/170 有关。我真的希望能够使用 dplyr 实现这种任务的优雅方法。期待看到这个问题的答案。你的问题真的很有趣,请尽力使其可重现,以便其他人可以帮助你。例如使用 mtcars 数据集。 - dickoa
好的,已经完成了,虽然有些粗糙 :) - nzcoops
也许是@hadley。这可能是一个不太恰当的词汇选择,但我更喜欢将这个(我的当前工作plyr版本)视为更像是查找而不是任何类型的连接。正如我在下面Troy的答案评论中所暗示的,我不喜欢“连接”的想法,因为你会得到n1 x n2条记录的结果数据框/表(然后进行操作)。 - nzcoops
查找只是一种连接类型。我认为我们只是在使用不同的语言表达相同的事情。 - hadley
好的,我是指我的措辞不太恰当。 - nzcoops
显示剩余2条评论
1个回答

2
怎么样:
merge(mtcars,xtra,by="models") %.% group_by(models) %.% summarise(sum(newmpg)) 

编辑 抱歉,我觉得这是你想要的内容;

# from what I can tell of your data:
dat_new<-data.frame(hrn=c("P1","P2"),dov=42000)
event<-data.frame(hrn=sample(dat_new$hrn,20,T),doa=41990+sample(1:20,20),event_code=sample(2:8,20,T))


merge(dat_new,event,by="hrn") %.%
filter(doa<=dov) %.% 
group_by(hrn,dov) %.%
summarise(dka2=length(event_code[event_code==2]),
          dka3=length(event_code[event_code==3]),
          dka8=length(event_code[event_code==8]))

Source: local data frame [2 x 5]
Groups: hrn

  hrn   dov dka2 dka3 dka8
1  P1 42000    2    1    0
2  P2 42000    1    0    1

很抱歉 - 在编辑之前,我混淆了doa和dov - 根据您的表格中还有什么内容,您可能需要调整merge(,by=c("x",..))调用。


3
你也可以使用 dplyr::inner_join() ;)。 - hadley
1
谢谢Troy。这个完成了任务,而且在我的数据集上比plyr更快(dat_new中有约15k条记录,event中有900条)。但我不太想将它们作为第一步合并。一个主题在一个数据集中有25条记录,在另一个数据集中有15条记录,合并后会有375条记录。所以虽然速度更快,但感觉很反直觉/粗糙。无意冒犯!这可能是我们现在最好的解决方案!此外,输出不完全相同,plyr的输出与dat_new具有相同数量的行,而此解决方案则删除所有(dka2/3/8)都为0的行。 - nzcoops
在我的数据上,非常简单的测试表明,对于这个解决方案,inner_join 比 merge 运行速度快了约3倍。@hadley - nzcoops

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接