我希望有人可以提供帮助,我试图加快申请功能,我尝试了一些技巧,但它仍然很慢,我想知道是否还有人提出更多建议。
我的数据如下:
myData= data.frame(ident=c(3,3,4,4,4,4,4,4,4,4,4,7,7,7,7,7,7,7),
group=c(7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8),
significant=c(1,1,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0),
year=c(2003,2002,2001,2008,2010,2007,2007,2008,2006,2012,2008,
2012,2006,2001,2014,2012,2004,2007),
month=c(1,1,9,12,3,2,4,3,9,5,12,8,11,3,1,6,3,1),
subReport=c(0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0),
prevReport=c(1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1))
我希望得到一个像这样的数据框:
results=data.frame(ident=c(3,4,7),
significant=c(1,0,1),
prevReports=c(2,6,7),
subReport=c(0,1,0),
group=c(7,7,8))
为了做到这一点,我编写了下面的代码并快速完成,我尝试转换为数据表并使用rbindlist而不是rbind,我已经在几个线程中找到了建议。我也试过parLapply,但我仍觉得这个过程很慢,(我想在大约250,000个数据点上做这个)。
dt<-data.table(myData)
results<-NULL
ApplyModel <- function (id,data) {
dtTemp<-dt[dt$ident== id,]
if(nrow(dtTemp)>=1){
prevReport = if(sum(dtTemp$prevReport)>=1) sum(dtTemp$prevReport) else 0
subsequentReport = if(sum(dtTemp$subReport)>=1) 1 else 0
significant = as.numeric(head(dtTemp$sig,1))
group = head(dtTemp$group,1)
id= as.numeric(head(dtTemp$id,1))
output<-cbind(id, significant ,prevReport,subsequentReport ,group)
output<-output[!duplicated(output[,1]),]
print(output)
results <- rbindlist(list(as.list(output)))
}
}
results<-lapply(unique(dt$ident), ApplyModel)
results<-as.data.frame(do.call(rbind, results))
欢迎任何有关如何加快速度的建议!我认为这可能与子集有关,我想将函数应用于基于唯一值的子集,但我认为lapply实际上更多的是将函数应用于每个值,因此子集在某种程度上击败了对象...
答案 0 :(得分:2)
在这里,您的代码会产生错误:
结果&lt; -lapply(unique(dt $ ident),ApplyModel) dt $ ident中的错误:'closure'类型的对象不是可子集化的
在我看来,你正在寻找tapply而不是lapply。使用tapply,你可以用更简洁的方式大致表达上述内容:
results2 <- data.frame(significant = tapply(myData$significant, myData$ident, function(x) return(x[1])),
prevreports = tapply(myData$prevReport, myData$ident, sum),
subReports = tapply(myData$subReport, myData$ident, function(x) as.numeric(any(x==1))),
group = tapply(myData$group, myData$ident, function(x) return(x[1])))
应该做同样的工作但更具可读性。现在,除了巨大的数据集之外,这应该很快。在大多数情况下,等待R完成工作比花更多时间编程要快。使这更快的一种方法是使用data.table包的强大功能,但只是调用它并不能解决问题。你需要学习它非常特殊的语法。请检查一下,这样给出的代码实在太慢了。 如果它真的太慢,请检查:
library(data.table)
first <- function(x) x[1]
myAny <- function(x) as.numeric(any(x==1))
myData <- data.table(myData)
myData[, .(significant=first(significant),
prevReports=sum(prevReport),
subReports=myAny(subReport),
group=first(group)), ident]
答案 1 :(得分:2)
您可以使用dplyr
:
require(dplyr)
new <- myData %>% group_by(ident) %>%
summarise(first(significant),sum(prevReport),(n_distinct(subReport)-1), first(group)) %>%
data.frame()