Search code examples
rlistloopslapplysapply

Convert loop to apply while building list


I am trying to build a list of lists in R with an apply function rather than a loop, but I'm having trouble converting a working loop into an lapply format. Allow me to explain the situation a bit more:

I have a function in R (getDetails) that retrieves details associated with parameters that I pass to the function and returns the result in a list. The function works well if I pass it a single record, and I've also built a loop that that allows me to loop through a dataframe one row at a time, and pass the elements of the dataframe, row-by-row to my function which in turn returns a list to the i-th element of my list of lists (detailsList[[i]]). I am trying to figure out how to convert my for loop into an apply function. Can you assist me with this? I've created a toy example, that if I can get working, will allow me to generalize this to my actual getDetails function.

#use cars dataset for an example
data(cars)
#get number of rows
numrows<-dim(cars)[1]
#initialize empty list
detailsList<-vector("list", numrows)

#This is a toy example of the loop I want to convert to an apply
#I'm having trouble because this builds up a list and returns the results
#to my detailsList one element at a time and I'm not sure how to do this 
#in an apply.
for (i in 1:numrows){
  detailsList[[i]]<-getDetails(cars[i,])
}

detailsList

getDetails<-function(parameters){
   valueA<-parameters[1]+45
   valueB<-parameters[1]+10
   list(valueA, valueB)
}

UPDATE:

I thought I just figured this out, but it seems when I do this, I get an third dimension in my list so when I use this:

allDetails <- lapply(1:numrows, function(i)  getDetails(cars[i,]))

the second element of the first list can only be accessed with allDetails[[1]][[1]][2] instead of with allDetails[[1]][2] as I was hoping. Does anyone know what I'm doing wrong here?


Solution

  • I think I just figured this out after a little help from @Parfait (thank, @Parfait!). In case anyone else was looking for an answer, this worked for me, but I'd welcome any other answers:

    lapply(1:numrows, function(i)  getDetails(cars[i,]))
    

    and I had to modify my function to return a vector instead of a list:

    getDetails<-function(parameters){
       valueA<-parameters[1]+45
       valueB<-parameters[1]+10
       c(valueA, valueB)
    }