Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

loop through a list of dataframe in R and apply if else function

Tags:

r

I have a list of dataframe and would like to apply if else function through the list

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))
 }

I would like to loop through each df and if the sum of the cens variable in an individual df = 0 (i.e. df2) then apply the reg.stats function, otherwise apply the other.stats function.

In the real dataset, I have a list of 50+ dfs and what I did in the past was to manually pick out the dfs where all the cens = 0 and use the lapply function. It was ok but if I separate the dataframe and use lapply separate for each list and then combine the results, the order is changed and then I need to reorder the result. Is there a quicker, cleaner way to do this?

  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))
like image 568
Amateur Avatar asked Dec 12 '12 17:12

Amateur


1 Answers

It works with if and else but not with ifelse since the latter will only return the first value of the function result:

lapply(df.list, function(i) if (sum(i$cens) == 0) reg.stats(i$res) 
                            else other.stats(i$res,i$cens))

The result:

[[1]]
[1] 0.402693 1.467128

[[2]]
[1] 0.3427096 2.4269668

[[3]]
[1] 0.3731172 1.8051164

[[4]]
[1] 0.3883753 2.0028039

By the way: There's no need for separate functions. It can all be done within one command:

lapply(df.list, function(i) {detects <- log(i$res[i$cens == 0])
                             c(exp(mean(detects)), exp(sd(detects)))})
like image 113
Sven Hohenstein Avatar answered Nov 15 '22 09:11

Sven Hohenstein