Reputation: 353
I have a question about using lapply
with lists of dataframes. Suppose I have two lists:
list1<-list(data1,data2)
list2<-list(data3,data4)
I want to write a function that appends a column and row from one dataframe to another. This is my function:
append<-function(origin.data, destin.data){
vec.to.append<-origin.data[,1]
#add as the first column
destin.data<-cbind(vec.to.append, destin.data)
#add as first row
vec.to.append<-t(c(0, vec.to.append))
destin.data<-rbind(vec.to.append, destin.data)
return(destin.data)
}
This works fine if I run
append(list1[[1]], list2[[1]])
or
append(list1[[2]], list2[[2]])
but gives me an error when I try to use lapply
:
trial<-lapply(list1, append, destin.data=list2)
The error looks straightforward:
Error in rbind(vec.to.append, destin.data) : number of columns of matrices must match (see arg 2)
but as I checked the dimensions of my dataframes and vector, all looked fine. Plus, the function runs and gives the expected result if I do not use lapply
but do it "argument by argument". Can somebody help me out?
By the way, I saw the answer here: Using lapply with changing arguments but applying my function over the list names gives an empty result:
prova<-lapply(names(list1), append, destin.data=list2)
prova
list()
Clearly, I am missing something!
Upvotes: 3
Views: 2177
Reputation: 9592
lapply(list1, append, destin.data=list2)
is equivalent to:
list(append(list1[[1]], list2),
append(list1[[2]], list2)
Which is not what you want. If you want to pair up list1 and list2, element-wise, you should do:
lapply(seq_along(list1), function(i) append(list1[[i]], list2[[i]])
This is equivalent to:
list(append(list1[[1]], list2[[1]]),
append(list1[[2]], list2[[2]])
which is what you do want, right?
edit: as the other answer says, you can also use mapply
, which is a little tidier, but this is the lapply
-based solution. Result is the same in either case.
Upvotes: 1
Reputation: 546073
lapply
only iterates over one list. The last argument you pass is passed on to the function as-is (i.e. the function append
gets passed all of list2
rather than just one element).
You can use Map
or mapply
instead. Note that the order of the arguments here is reversed in comparison to lapply
:
result = Map(append, list1, list2)
Upvotes: 1