首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R数据表用户定义的函数速度较慢

R数据表用户定义的函数速度较慢
EN

Stack Overflow用户
提问于 2018-07-29 02:25:58
回答 1查看 120关注 0票数 1

我有两个数据表dt1dt2dt1由单个指示符ii的列表和时间指示符tt的列表构成。一个包含3个人和两个时间段的示例如下:

代码语言:javascript
复制
library(data.table)
ii_ind = c(1,2,3)
tt_ind = c(2010,2011)
dt1 = merge(x=data.frame(ii =ii_ind) , y = data.frame(jj=ii_ind))
dt1 = merge(x=dt1 , y = data.frame(tt = tt_ind))
dt1 = as.data.table(dt1)
dt1 = dt1[ii != jj]

dt1表示动态网络中的二元组(边的指示器在第四列,但与我在这里尝试做的事情无关)。

dt2有三列,分别表示单个ii、时间tt和一个整数变量zz。例如:

代码语言:javascript
复制
dt2 = data.table(ii = c(1,1,1,1,1,2,2,2,2,3,3), 
                 tt = c(2010,2010,2011,2011,2011,2010,2010,2011,2011,2010,2011),
                 zz = c(1,2,1,2,3,1,2,1,2,3,3))

我想在dt1中有一个新的列,比如count.zz,它统计(ii,tt)(jj,tt)有相同zz的实例的数量。我是这样做的:

代码语言:javascript
复制
setkey(dt1,ii,jj,tt)
setkey(dt2,ii,tt)
dt1[,count.zz:= as.integer(0)]
count.zz.fun = function(z.ii,z.jj,z.tt){
  return(length(intersect(dt2[.(z.ii,z.tt),zz],dt2[.(z.jj,z.tt),zz])))
}
dt1[,count.zz := count.zz.fun(ii,jj,tt), by = c("ii","jj","tt")]

在这个例子中,我们使用了ii=1,jj=2,tt=2010count.zz=2,因为(ii,tt)(jj,tt)都有zz=1zz=2的共同点。ii=1,jj=3,tt=2010count.zz=0,因为zz=1(ii,tt)zz=2不与(jj,tt)zz集合相交,即zz=3

我想知道是否有更快的方法来做这件事。由于dt1zz中的2.3为百万行,范围从1100,在标准的台式机PC上运行上述操作大约需要2-3 hours

我已经标记了igraph,因为上面的结构是一个网络,可能有一种使用igraph的更快的方法来完成这一点,但我不知道。

@Ryan建议使用sum(a %in% b)而不是length(intersect(a,b))。下面是两个函数的比较:

代码语言:javascript
复制
library(tictoc)
N = 1000000
R = 1000
a = seq(from=1,to=N, by = 2)
b = seq(from=1,to=N, by = 3)

t = tic() 
for (rr in 1:R){
  sum(a %in% b)
}
t_sum = toc(t)

t = tic() 
for (rr in 1:R){
  length(intersect(a,b))
}
t_intersect = toc(t)

结果:

代码语言:javascript
复制
> t_sum = toc(t)
26.94 sec elapsed

> t_intersect = toc(t)
30.87 sec elapsed

@Ryan的建议将速度提高了约13-14%。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-30 09:04:05

根据dt2的大小,您可能希望在dt2上执行自联接,以便为tt和zz的组合生成所有的ii和jj对。然后执行连接并使用by=.EACHI计算长度

代码语言:javascript
复制
#find all pairs of ii and jj for combis of tt and zz
reldt <- dt2[dt2, .(ii=x.ii, jj=i.ii, tt, zz), on=.(tt,zz)]

#join and find the number of occurrence
reldt[dt1, on=.(ii,jj,tt), .N, by=.EACHI]

输出:

代码语言:javascript
复制
    ii jj   tt N
 1:  2  1 2010 2
 2:  3  1 2010 0
 3:  1  2 2010 2
 4:  3  2 2010 0
 5:  1  3 2010 0
 6:  2  3 2010 0
 7:  2  1 2011 2
 8:  3  1 2011 1
 9:  1  2 2011 2
10:  3  2 2011 0
11:  1  3 2011 1
12:  2  3 2011 0
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51574100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档