Joaquin Joaquin - 22 days ago 7
R Question

Get element number of list while iterating through it

I have a list of the following structure,

myList <- replicate(5, data.frame(id = 1:10, mean = runif(10)), simplify =F)


and I want to reduce it with a merge

myList %>% reduce(function(x, y) merge(x, y, by = 'id'))


That, however, leads to the following colnames:

id mean.x mean.y mean.x mean.y mean


While I would like something like

id mean1 mean2 mean3 mean4 mean5


Where the numbers are based on the order of
myList
.

Obviously I could iterate over
1:length(myList)
, but I find this solution unelegant. Other option would be to introduce a check in the reducing function, but that would indue a new linear time search for each element of the list, so I don't believe it to be very efficient.

Is there another way to achieve this?

Answer Source

A possible solution:

myList <- mapply(function(x,y) {names(x)[2] = paste0('mean',y); x}, myList, 1:length(myList), SIMPLIFY = FALSE)

Reduce(function(x, y) merge(x, y, by = 'id'), myList)

which gives:

   id     mean1     mean2      mean3      mean4      mean5
1   1 0.1119114 0.4193226 0.86619590 0.52543072 0.52879193
2   2 0.4630863 0.8786721 0.02012432 0.77274088 0.09227344
3   3 0.9832522 0.4687838 0.49074271 0.01611625 0.69919423
4   4 0.7017467 0.7845002 0.44692958 0.64485570 0.40808345
5   5 0.6204856 0.1687563 0.54407165 0.54236973 0.09947167
6   6 0.1480965 0.7654041 0.43591864 0.22468554 0.84557988
7   7 0.0179509 0.3610114 0.45420122 0.20612154 0.76899342
8   8 0.9862083 0.5579173 0.13540519 0.97311401 0.13947602
9   9 0.3140737 0.2213044 0.05187671 0.07870425 0.23880332
10 10 0.4515313 0.2367271 0.65728768 0.22149073 0.90578043