3

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!

6
  • @nongkrong Thanks. I think I am using lapply over a list of dataframes, with the intention of applying the function append to each dataframe element. Indeed, append takes two dataframes as inputs and gives a dataframe as output. In short, I am not sure I understand your comment and why it explains my lapply failure. Could you please elaborate? Commented Aug 12, 2015 at 17:19
  • Try lapply(list1,function(x)apply(x[[1]],x[[2]])) Commented Aug 12, 2015 at 17:27
  • @MichaelChirico Thanks, Michael. Just a clarification: did you mean lapply(list1, function(x) append(x[[1]], x[[2]]))? Also, what is x? Can you please explain? Thank you. Commented Aug 12, 2015 at 17:32
  • your data1-data4 are matrices not data.frames, correct? Commented Aug 12, 2015 at 17:34
  • They are data.frames. Commented Aug 12, 2015 at 17:38

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes! That is what I want. I'll give it a try now and report back!
1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.