Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R:按条件对多列应用函数(与聚合类似)_R - Fatal编程技术网

R:按条件对多列应用函数(与聚合类似)

R:按条件对多列应用函数(与聚合类似),r,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= lis

我很难描述这一点,但以下是我的示例:

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

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

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)
库(dplyr)
getValues%选择(年,值)
data.frame(cbind(值、名称)
}
将该函数应用于第一维中的任何矩阵

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)
listTemp您可以使用来执行此操作:

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
您可以在之后进行重塑以获得所需的输出。我知道了如何使用来实现这一点,但这很难看。我必须使用函数接受的几乎每个参数来自定义结果以匹配所需的输出。假设您将上述结果存储为
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

Adiana谢谢你的回答!如果我错了,请纠正我,但我相信它遗漏了一个我无法理解的关键部分:(x1*x2)/sum(x1)每一年都要做一次,每个数据框都有几年。这就是我遇到问题的原因——基本上我想使用apply for the Threed dimensional array and aggregate,这样它每年都会给我一个答案(apply,c(1),fun=aggregate(x,by=list)(x$year,fun=(x1*x2)/sum(x1))。但是,聚合只对一个向量起作用,因此我不能同时使用x1和x2。您的公式
(val1*val2)/sum(val1)
。分母中的
sum(val1)
是有意义的;它在
val1
上聚合。但是
(val1*val2)分子中的
不聚合。如何聚合分子中每个
站点
/
组存在的多个
val1
val2
值?如果要为每个
站点
/
组获得单个值,则需要聚合为单个值在某个时刻。或者你不想聚合,从而得到每个
站点
/
组的值向量?我提到聚合的唯一原因是因为我知道它是唯一一个按唯一组执行函数的函数。我需要该函数逐行乘以列val1和val2,这样每行都有一个produc两列的t,然后这些乘积的和除以val1的和,但这都是每年都要做的。关于adana的答案,请参阅我的评论。你的意思是
sum(val1*val2)/sum(val1)
?如果测试数据没有为所有组生成相同的值,那么出于测试目的,可能会更好。我运行了这段代码,它可以工作,但似乎计算时间是指数的,而不是线性的。我将不同数量的站点分组在一起。每个站点运行76个站点需要1.34秒,每个站点运行3.78秒运行172个站点。当我到达近500个站点中最大的横断面时,这将是前所未有的。你知道为什么时间是指数型的吗?我有足够的ram来进行操作(4-5次免费演出)