我有一个数据框列表,并希望通过列表
应用if else函数df1= data.frame(letter=LETTERS[1:5], res=runif(10), cens=rep(0:1,5))
df2= data.frame(letter=LETTERS[1:5], res=runif(10), cens=rep(0,5))
df3= data.frame(letter=LETTERS[1:5], res=runif(10), cens=rep(0:1,5))
df4= data.frame(letter=LETTERS[1:5], res=runif(10), cens=rep(0,5))
df.list=list(df1,df2,df3,df4)
reg.stats = function(var1){
gm.reg=exp(mean(log(var1)))
gsd.reg=exp(sd(log(var1)))
return(c(gm.reg,gsd.reg))
}
other.stats = function(obs,cens){
nondetects <- obs[cens==1]
detects <- obs[cens== 0]
gm.other=exp(mean(log(detects)))
gsd.other=exp(sd(log(detects)))
return(c(gm.other,gsd.other))
}
我想循环遍历每个df,如果个体df = 0(即df2)中的cens变量之和,则应用reg.stats函数,否则应用other.stats函数。
在真实数据集中,我有一个50多个dfs的列表,我过去做的是手动挑选所有cens = 0的dfs并使用lapply函数。没关系,但如果我将数据框分开并为每个列表单独使用lapply然后合并结果,则更改顺序,然后我需要重新排序结果。有更快,更清洁的方法吗?
uncens.list = df.list[c(2,4)]
uncens.res= lapply(uncens.list, function(i) reg.stats(i$res))
cens.list = df.list[c(1,3)]
cens.res.=lapply(cens.list,function(i) other.stats(i$res,i$cens))
答案 0 :(得分:5)
它适用于if
和else
,但不适用于ifelse
,因为后者只会返回函数结果的第一个值:
lapply(df.list, function(i) if (sum(i$cens) == 0) reg.stats(i$res)
else other.stats(i$res,i$cens))
结果:
[[1]]
[1] 0.402693 1.467128
[[2]]
[1] 0.3427096 2.4269668
[[3]]
[1] 0.3731172 1.8051164
[[4]]
[1] 0.3883753 2.0028039
顺便说一下:不需要单独的功能。它可以在一个命令中完成:
lapply(df.list, function(i) {detects <- log(i$res[i$cens == 0])
c(exp(mean(detects)), exp(sd(detects)))})
答案 1 :(得分:0)
具体来说,功能llply?
如果您编写了一个包装函数来确定在给定cens值的情况下调用哪个stats函数,那么您似乎可以使用包装函数调用llply。