【发布时间】:2014-10-14 20:58:24
【问题描述】:
我正在尝试找到最有效的方法来循环遍历数据框并按 5 组进行聚类观察。例如,如果我有:
group <- c(1,2,3,4,5,6,7,8,9,10)
people <- c(1,2,3,4,4,3,2,1,2,3)
avg_age <- c(5,10,15,20,25,30,35,40,45,50)
data <- data.frame(group,people,age)
这应该会生成
group people avg_age
1 1 1 5
2 2 2 10
3 3 3 15
4 4 4 20
5 5 4 25
6 6 3 30
7 7 2 35
8 8 1 40
9 9 1 45
10 10 2 50
然后,我想创建另一个包含至少 5 人的群组“集群”,并为“集群”设置加权平均年龄。但我想以最有效的方式执行此操作,方法是遍历数据集并按顺序添加组,直到组成一个至少有 5 人的“集群”。我们的数据应该如下所示:
group people age cluster tot_ppl avg_age
1 1 1 5 1 6 11.67
2 2 2 10 1 6 11.67
3 3 3 15 1 6 11.67
4 4 4 20 2 8 22.5
5 5 4 25 2 8 22.5
6 6 3 30 3 5 32
7 7 2 35 3 5 32
8 8 1 40 4 6 46.67
9 9 2 45 4 6 46.67
10 10 3 50 4 6 46.67
我想在一个大约有 10,000 个观察值而不是 10 个的数据集上做这样的事情。有没有人知道一种有效的方法来解决这个问题?
这是我目前所得到的,但是,对于我正在处理的一些数据样本,实际上有接近 200 万个观测值,因此运行可能需要相当长的时间......
data$cluster <- 0
count=0
while (min(data$cluster)==0)
#while (max(data$cluster)<=10)
{
count = count+1
data$cum <- ave(data$people, by=list(data$zipcode,data$cluster), FUN=cumsum)
data$a <- floor(data$cum/10)
data$b <- data$cum-data$n1
data$c <- floor(data$b/10)
data$cluster[data$c==0] = data$cluster[data$c==0]+1
}
extravars <- c('cum','a','b','c')
for (inc.source in extravars){
eval(parse(text = paste("data$",inc.source,"<-NULL",sep="")))
}
data$tot_ppl <- ave(data$people, by=list(data$zipcode,data$cluster), FUN=sum)
data$cluster[data$tot_ppl<10]=data$cluster[data$tot_ppl<10]+1
data$tot_ppl <- ave(data$people, by=list(data$zipcode,data$cluster), FUN=sum)
data2 <- data
for (i in 3:(ncol(data2)-3)){
data2$x <- data2[ ,i]*data2$tot_ppl
data2$x <- ave(data2$x, by=list(data2$zipcode,data2$cluster), FUN=sum)
data2$x <- round(data2$x/data2$tot_ppl,digits=2)
data2[ ,i] = data2$x
}
data2$x <- NULL
虽然这可行,但需要几个小时才能运行,所以如果有人知道如何提高效率或改进它,我将不胜感激。谢谢!
【问题讨论】:
-
您是否编写过一种“低效”的方式?如果是这样,请显示您已经尝试过的代码。 10,000 次观察真的需要很长时间吗?
标签: r loops vectorization