我编写了一个非常类似于R的代码来进行一些相对简单的计算,但是虽然代码似乎有用,但效率非常低,而且我的计算机内存无法将其拉下来。 / p>
我有一个名为data.frame
的{{1}},其中有四列包含dat
(firm_id
),character
(pnum
),{{ 1}}(numeric
)和class
(character
)。我总共有100,000行:200个不同的date
,90,000个唯一Date
,大约31,000个唯一firm_id
和大约pnum
。
每个class
对于单个date
都是唯一的。 pnum
已分配给多个firm_id
元素(因此,如果有5个pnum
元素,则数据框中会重复class
5次。pnum
会不会因class
而异,但同一date
的多个pnum
可能在同一天。pnum
。
这是一个简短的firm_id
zero NAs
该代码旨在执行以下操作:
对于每一个dput
:
dput(dat[1:50])
structure(list(firm_id = c("A&O", "A&O", "A&O", "A&O", "A&O","A&O", "A&O",
"A&O", "A&O", "A&O", "A&O", "A&O", "A&O", "A&O",
"A&O", "A&O", "A&O", "A&O", "A&O", "A&O", "A&O",
"A&O", "A&O", "A&O", "A&O", "A&O", "A&O", "A&O",
"A&O", "A&O", "A&O", "A&O", "A&O", "A&O", "AAT",
"AAT", "AAT", "AAT", "AAT", "AAT", "AAT", "AAT",
"AAT", "AAT", "AAT", "AAT", "AAT", "AAT", "AAT", "AAT"),
pnum = c(5259588, 5259588, 5259588, 5259588, 7049668, 7049668,
7049668, 7049668, 7049668, 7049668, 7049668, 7183616,
7183616, 7183616, 7183616, 7183616, 7183616, 7183616,
7183616, 7208818, 7208818, 7208818, 7208818, 7208818,
7208818, 7208818, 7122882, 7122882, 7122882, 7122882,
7122882, 7122882, 7122882, 7122882, 6413822, 6413822,
6413822, 6413822, 6413822, 6413822, 6413822, 6413822, 6413822,
6750507, 6750507, 6750507, 6750507, 6750507, 6750507, 6750507),
class = c("184/1.5", "222/110", "251/100", "251/324", "257/330",
"257/331", "257/401", "257/E29.027", "257/E29.134",
"257/E29.136", "257/E29.146", "257/341", "257/342",
"257/343", "257/401", "257/723", "257/E23.052",
"257/E23.079", "257/E25.016", "257/666", "257/676",
"257/E23.024", "257/E23.026", "257/E23.037", "257/E23.044",
"257/E23.052", "257/48", "257/666", "257/723", "257/778",
"257/E23.052", "257/E25.013", "257/E25.029", "257/E29.267",
"257/331", "257/E29.027", "257/E29.066", "257/E29.133",
"257/E29.146", "438/268", "438/270", "438/272", "438/430",
"257/302", "257/328", "257/330", "257/396",
"257/E29.027", "257/E29.066", "257/E29.133"),
date = structure(c(7953, 7953, 7953, 7953, 10463, 10463,
10463, 10463, 10463, 10463, 10463, 11777,
11777, 11777, 11777, 11777, 11777, 11777,
11777, 12619, 12619, 12619, 12619, 12619,
12619, 12619, 12724, 12724, 12724, 12724,
12724, 12724, 12724, 12724, 10703, 10703,
10703, 10703, 10703, 10703, 10703, 10703,
10703, 10703, 10703, 10703, 10703, 10703,
10703, 10703), class = "Date")),
.Names = c("firm_id", "pnum", "class", "date"),
class = c("data.table", "data.frame"),
row.names = c(NA, -50L))
的{{1}}元素。 firm_id
元素与同一class
的每个pnum
个class
元素进行比较,前提是class
之间的差距(与相应的pnum
相关联的比较小于5年。 [以大写字母添加,以避免混淆。迈克尔下面提供的解决方案将焦点firm_id
与公司前五年dates
的投资组合进行了比较] 我目前的代码如下:(我知道,相信我,我知道)
pnum
编辑1:代码会生成一个data.frame pnum
,第一列pnum
包含原始#Step 1: Create a vector of unique firms and a data.frame with all
# `pnum`, `firm_id`, and `date` but without the `class` data
firms <- (unique(dat$firm_id))
patents <- data.frame(unique(dat$pnum))
patents$id <- dat$firm_id[match(patents$unique.dat.pnum, dat$pnum)]
patents$date <- dat$date[match(patents$unique.dat.pnum, dat$pnum)]
colnames(patents) <- c("pnum", "id", "date")
#Step 2: Set-up variables needed to store the results
library(gtools)
startrow <- 0
df <- data.frame()
#Step 3: Loop around all firms
for(i in 1:length(firms)){
startrow <- startrow + length(patents$id[patents$id == firms[i - 1]])
subdat <- dat[dat$firm_id == firms[i]]
subpat <- unique(subdat$pnum)
dt <- data.frame()
#Step 4: Find which of the `pnum` fit within the 5 year time frame
for(j in 1:length(subpat)){ # Number of unique patents in subdat
class.now <- subdat$class[subdat$pnum == subpat[j]]
ref.pat <- unique(subdat$pnum[(subdat$date > (patents$date[startrow + j] - 5*365) & subdat$date < (patents$date[startrow + j]))])
if (invalid(ref.pat) == T ) ref.pat <- NA
m <- data.frame(cbind(orig.pat = rep(patents$pnum[startrow + j],length(ref.pat))),ref.pat = NA, jac = NA)
#Step 5: Compare the focal `pnum` with each of the prior ones within the
# 5 year time frame and calculate a Jaccard index
for(k in 1:length(ref.pat)){
class.ref <- subdat$class[subdat$pnum == ref.pat[k]]
m$ref.pat[k] <- ref.pat[k]
m$jac[k] <- sum(class.now %in% class.ref)/(length(class.now) + length(class.ref) - length(class.now %in% class.ref))}
dt <- data.frame(rbind(dt, m)) ; rm(m)
}
df <- data.frame(rbind(df, dt))
rm(dt) ; print(i)
}
,第二列df
包含与之相关的专利比较了origpat
,第三列pnum
是ref.pat
和orig.pat
的Jaccard索引。
非常欢迎任何有关改善这项工作的建议!
答案 0 :(得分:1)
我相信这是正确的,我承认我在原始代码中丢失了一些东西。描述
# helper function for conciseness below
jac <- function(cn, cr) sum(idx <- cn %in% cr) /
(length(cn) + length(cr) - length(idx))
setkey(dat, pnum, firm_id) #for faster exclusive subsetting
dat[ , {x<-date[1]; cs <- class #assign these so there's no scoping issue below
#Now that we're within a (firm_id, pnum) subset,
# we go back to the original table and subset to
# the _same_ firm but NOT the same patent
# (note that the current firm and pnum are stored
# in .BY[[1]] and .BY[[2]], respectively)
dat[firm_id == .BY[[1]] & pnum != .BY[[2]]
#having subsetted to everything by the same firm
# (except things with the same `pnum`), we
# check which `pnum` satisfy the within-five-years
# criterium; for those that do, we calculate `jac`
][abs(date - x) <= 365 * 5, jac(cs, class)]},
by = .(firm_id, pnum)] #we do this for each `firm_id` and `pnum`