【发布时间】:2016-11-26 22:02:18
【问题描述】:
这个问题与我的previous one 有关。这是一个小样本数据。我同时使用了data.table 和data.frame 来找到更快的解决方案。
test.dt <- data.table(strt=c(1,1,2,3,5,2), end=c(2,1,5,5,5,4), a1.2=c(1,2,3,4,5,6),
a2.3=c(2,4,6,8,10,12), a3.4=c(3,1,2,4,5,1), a4.5=c(5,1,15,10,12,10),
a5.6=c(4,8,2,1,3,9))
test.dt[,rown:=as.numeric(row.names(test.dt))]
test.df <- data.frame(strt=c(1,1,2,3,5,2), end=c(2,1,5,5,5,4), a1.2=c(1,2,3,4,5,6),
a2.3=c(2,4,6,8,10,12), a3.4=c(3,1,2,4,5,1), a4.5=c(5,1,15,10,12,10),
a5.6=c(4,8,2,1,3,9))
test.df$rown <- as.numeric(row.names(test.df))
> test.df
strt end a1.2 a2.3 a3.4 a4.5 a5.6 rown
1 1 2 1 2 3 5 4 1
2 1 1 2 4 1 1 8 2
3 2 5 3 6 2 15 2 3
4 3 5 4 8 4 10 1 4
5 5 5 5 10 5 12 3 5
6 2 4 6 12 1 10 9 6
我想使用开始和结束列值来确定子集的列范围(从 a1.2 到 a5.6 的列)并获得平均值.比如第一行,由于strt=1和end=2,我需要得到a1.2和a2.3的均值;在第三行,我需要得到 a2.3、a3.4、a4.5 和 a5 的平均值.6
输出应该是这样的向量
> k
1 2 3 4 5 6
1.500000 2.000000 6.250000 5.000000 3.000000 7.666667
这是我尝试过的:
解决方案 1:这使用 data.table 并在其上应用函数。
func.dt <- function(rown, x, y) {
tmp <- paste0("a", x, "." , x+1)
tmp1 <- paste0("a", y, "." , y+1)
rowMeans(test.dt[rown,get(tmp):get(tmp1), with=FALSE])
}
k <- test.dt[, func.dt(rown, strt, end), by=.(rown)]
解决方案 2:这使用 data.frame 并在其上应用一个函数。
func.df <- function(rown, x, y) {
rowMeans(test.df[rown,(x+2):(y+2), drop=FALSE])
}
k1 <- mapply(func.df, test.df$rown, test.df$strt, test.df$end)
解决方案 3:这使用 data.frame 并循环遍历它。
test.ave <- rep(NA, length(test1$strt))
for (i in 1 : length(test.df$strt)) {
test.ave[i] <- rowMeans(test.df[i, as.numeric(test.df[i,1]+2):as.numeric(test.df[i,2]+2), drop=FALSE])
}
基准测试表明解决方案 2 是最快的。
test replications elapsed relative user.self sys.self user.child sys.child
1 sol1 100 0.67 4.786 0.67 0 NA NA
2 sol2 100 0.14 1.000 0.14 0 NA NA
3 sol3 100 0.15 1.071 0.16 0 NA NA
但是,这对我来说还不够好。考虑到我的数据大小,这些函数需要运行几天才能得到输出。我确信我没有充分利用data.table 的力量,而且我也知道我的函数很糟糕(它们引用全局环境中的数据集而不传递它)。不幸的是,我的深度不够,不知道如何解决这些问题并使我的功能快速。我将非常感谢任何有助于改进我的功能或指出替代解决方案的建议。
【问题讨论】:
-
列是否总是按顺序排列
a1、a2、a3、...等? -
是的,它们总是有序的。这就是原因,我得到第一个和最后一个列标识符,并使用它来子集中间列。
标签: r performance function dataframe data.table