R:按条件在多列上应用函数(如聚合)

时间:2016-03-22 22:51:01

标签: r

我很难描述这个,但这是我的例子:

n=20
years= c(rep(2000,n), rep(2001,n), rep(2002,n), rep(2003,n), rep(2004,n))
val1= c(rep(7,n), rep(8,n), rep(9,n), rep(10,n), rep(11,n))
val2= c(rep(1:20,5))

tmp= cbind(val1,val2,years)

test= array(dim=c(2,100,3), dimnames= list(c("site1","site2"),NULL,c("val1","val2","years")))
test[1,,]= tmp
test[2,,]= tmp

所以我想做的是每年的(val1 * val2)/ sum(val1),最后我希望输出为

site1 2000 value
site1 2001 value
.......
site2 2000 value
site2 2001 value
site2 2002 value
... and so on

2 个答案:

答案 0 :(得分:0)

声明一个执行给定维度所需操作的函数

library(dplyr)

getValues<-function(name){
temp<-data.frame(test[name,,])
values<- temp %>% group_by(years) %>% mutate(value=val1*val2/sum(val1)) %>% select(years,value)
data.frame(cbind(values,name)
}

将函数应用于第一维中的任何矩阵

listTemp<-lapply(dimnames(test)[[1]],getValues)

使用data.table包中的函数有效地绑定数据框

library(data.table)
allData<-rbindlist(listTemp)

答案 1 :(得分:0)

您可以使用tapply()执行此操作:

tapply(seq_len(prod(dim(test)[1:2])),list(rownames(test)[row(test[,,1L])],test[,,'years']),function(g) sum(test[,,'val1'][g]*test[,,'val2'][g])/sum(test[,,'val1'][g]));
##       2000 2001 2002 2003 2004
## site1 10.5 10.5 10.5 10.5 10.5
## site2 10.5 10.5 10.5 10.5 10.5

您可以随后重塑以获得所需的输出。我想出了如何使用reshape()来做这件事,但这很难看。我不得不使用函数接受的几乎所有参数来自定义结果以匹配所需的输出。假设您将上述结果存储为res,我们有:

reshape(data.frame(res,site=rownames(res),stringsAsFactors=F,check.names=F),dir='l',idvar='site',varying=seq_len(ncol(res)),times=colnames(res),v.names='value',timevar='year',new.row.names=seq_len(prod(dim(res))));
##     site year value
## 1  site1 2000  10.5
## 2  site2 2000  10.5
## 3  site1 2001  10.5
## 4  site2 2001  10.5
## 5  site1 2002  10.5
## 6  site2 2002  10.5
## 7  site1 2003  10.5
## 8  site2 2003  10.5
## 9  site1 2004  10.5
## 10 site2 2004  10.5