为R数据帧中的记录块创建序列号
我有一个相当大的数据集(按照我的标准),我想为记录块创建一个序列号。我可以使用plyr包,但是执行时间非常慢。下面的代码复制了一个大小相当的数据帧为R数据帧中的记录块创建序列号,r,data.table,plyr,R,Data.table,Plyr,我有一个相当大的数据集(按照我的标准),我想为记录块创建一个序列号。我可以使用plyr包,但是执行时间非常慢。下面的代码复制了一个大小相当的数据帧 ## simulate an example of the size of a normal data frame N <- 30000 id <- sample(1:17000, N, replace=T) term <- as.character(sample(c(9:12), N, replace=T)) date <-
## simulate an example of the size of a normal data frame
N <- 30000
id <- sample(1:17000, N, replace=T)
term <- as.character(sample(c(9:12), N, replace=T))
date <- sample(seq(as.Date("2012-08-01"), Sys.Date(), by="day"), N, replace=T)
char <- data.frame(matrix(sample(LETTERS, N*50, replace=T), N, 50))
val <- data.frame(matrix(rnorm(N*50), N, 50))
df <- data.frame(id, term, date, char, val, stringsAsFactors=F)
dim(df)
使用如下所示的data.table,相同的方法产生:
> with(test.dt, table(V1))
V1
1
24272
使用
数据表
dt = data.table(df)
test.dt = dt[,.N,"id,term"]
这里是一个时间比较。在生成数据集时,我使用了N=3000并将17000替换为1700
f_plyr <- function(){
test.plyr <- ddply(df, .(id, term), summarise, seqnum = 1:length(id),
.progress="text")
}
f_dt <- function(){
dt = data.table(df)
test.dt = dt[,.N,"id,term"]
}
library(rbenchmark)
benchmark(f_plyr(), f_dt(), replications = 10,
columns = c("test", "replications", "elapsed", "relative"))
还可以查看Hadley在dplyr
上的最新工作。如果dplyr
提供了额外的加速,我不会感到惊讶,因为很多代码都是用C语言重新编写的
更新:编辑代码,根据Matt的评论将
length(id)
更改为.N
。谢谢。我知道哈德利正在努力,但在此期间,我需要修复。速度的提高是疯狂的。在我的机器上,当我使用(test.df,table(V1))运行时,我看到的只是一个序列号1。我知道我们在模拟数据,但有些记录在分组中应该有多个记录。问题是data.table会对列进行不同的排序。如果使用head(plyr::arrange(test.dt,id))
,您将看到输出与test.plyr
相同,谢谢您的帮助。在我这方面最有可能出现用户错误,但无论我做什么,当我使用data.table解决方案时,V1的值只有1。见上文。@Btibert3是的,我认为拉姆纳特没有测试过这个。请将长度(id)
替换为.N
。在这一点上,此标签中有一些关于.N
的问题。@Btibert3请将(仅)length(id)
替换为.N
,而不是1:length(id)
替换为.N
。所以,1:.N
。或者,序列号(.N)
。
dt = data.table(df)
test.dt = dt[,.N,"id,term"]
f_plyr <- function(){
test.plyr <- ddply(df, .(id, term), summarise, seqnum = 1:length(id),
.progress="text")
}
f_dt <- function(){
dt = data.table(df)
test.dt = dt[,.N,"id,term"]
}
library(rbenchmark)
benchmark(f_plyr(), f_dt(), replications = 10,
columns = c("test", "replications", "elapsed", "relative"))
test replications elapsed relative
2 f_dt() 10 0.779 1.000
1 f_plyr() 10 132.572 170.182