我是一名初级R用户,尝试使用40,000行和300列的数据集。我找到了一个我想做的解决方案,但是我的机器需要一个多小时来运行我的代码,我觉得专家可以帮助我提供更快的解决方案(因为我可以在一半的时间内在excel中做到这一点) 。我会在最后发布我的解决方案。
我想做的是以下内容:
根据YYYYMMbucket列的值计算每列NY1到NYn的平均值。
将原始值除以其平均YYYYMMbucket值。
以下是我原始数据集的示例:
YYYYMMbucket NY1 NY2 NY3 NY4 1 200701.3 0.309 NA 20.719 16260 2 200701.3 0.265 NA 19.482 15138 3 200701.3 0.239 NA 19.168 14418 4 200701.3 0.225 NA 19.106 14046 5 200701.3 0.223 NA 19.211 14040 6 200701.3 0.234 NA 19.621 14718 7 200701.3 0.270 NA 20.522 15780 8 200701.3 0.298 NA 22.284 16662 9 200701.2 0.330 NA 23.420 16914 10 200701.2 0.354 NA 23.805 17310 11 200701.2 0.388 NA 24.095 17448 12 200701.2 0.367 NA 23.954 17640 13 200701.2 0.355 NA 23.255 17748 14 200701.2 0.346 NA 22.731 17544 15 200701.2 0.347 NA 22.445 17472 16 200701.2 0.366 NA 21.945 17634 17 200701.2 0.408 NA 22.683 18876 18 200701.2 0.478 NA 23.189 21498 19 200701.2 0.550 NA 23.785 22284 20 200701.2 0.601 NA 24.515 22368
这就是我的平均值:
YYYYMMbucket NY1M NY2M 1 200701.1 0.4424574 NA 2 200701.2 0.4530000 NA 3 200701.3 0.2936935 NA 4 200702.1 0.4624063 NA 5 200702.2 0.4785937 NA 6 200702.3 0.3091161 NA 7 200703.1 0.4159687 NA 8 200703.2 0.4491875 NA 9 200703.3 0.2840081 NA 10 200704.1 0.4279137 NA
我希望我的最终输出看起来如何:
NY1avgs NY2avgs NY3avgs 1 1.052117 NA 0.7560868 2 0.9023011 NA 0.7109456 3 0.8137734 NA 0.699487 4 0.7661047 NA 0.6972245 5 0.7592949 NA 0.7010562 6 0.7967489 NA 0.7160181 7 0.9193256 NA 0.7488978 8 1.014663 NA 0.8131974 9 0.7284768 NA 0.857904
我是这样做的:
首先,我使用“plyr”来计算我的平均值,这很简单:
test <- ddply(prf.delete2b,. (YYYYMMbucket), summarise,
NY1M = mean(NY1), NY2M = mean(NY2) ... ...))
然后使用以下一系列:
x <- c(1:40893)
lookv <- function(x,ltab,rcol=2) ltab[max(which(ltab[,1]<=x)),rcol]
NY1Fun <- function(x) (prf.delete2b$NY1[x] / lookv((prf.delete2b$YYYYMMbucket[x]),test,2))
NY2Fun <- function(x) (prf.delete2b$NY2[x] / lookv((prf.delete2b$YYYYMMbucket[x]),test,3))
NY1Avgs <- lapply(x, NY1Fun)
NY2Avgs <- lapply(x, NY2Fun)
我还尝试了以上的变体:
NY1Fun <- function(x) (prf.delete2b$NY1[x] / subset(test, YYYYMMbucket == prf.delete2b$YYYYMMbucket[x], select =c(NY1M)))
lapply(x, NY1Fun)
NYnFun的每个变体都需要20秒才能运行,因此这样做300次需要花费太长时间。任何人都可以推荐任何替代我发布的内容或指出我所做的任何新手错误吗?
答案 0 :(得分:3)
这是惯用的data.table
方法,它的工作速度非常快。
# CREATE DUMMY DATA
N = 1000
mydf = data.frame(
bucket = sample(letters, N, replace = T),
NY1 = runif(N),
NY2 = runif(N),
NY3 = runif(N),
NY4 = runif(N)
)
# SCALE COLUMNS BY AVG
library(data.table)
scale_x = function(x) x/ave(x)
mydt = data.table(mydf)
ans = mydt[,lapply(.SD, scale_x), by = 'bucket']
答案 1 :(得分:0)
怎么样:
test2 <- merge(prfdelete2b,test,all.x=TRUE)
test2[2:ncol(prefdelete2b)]/test2[(ncol(prefdelete2b)+1):ncol(test2)]
答案 2 :(得分:0)
在这种情况下,我会使用ave
而不是ddply
,因为ave
会返回与其输入长度相同的向量。 ave
只接受一个向量,因此您需要使用lapply
循环遍历data.frame的列。
myFun <- function(x, groupVar) {
x / ave(x, groupVar, FUN=function(y) mean(y, na.rm=TRUE))
}
relToMeans <- data.frame(prf.delete2b[1],
lapply(prf.delete2b[-1], myFun, groupVar=prf.delete2b[1]))