Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

foreach: Keep names

Tags:

foreach

r

Is there a way to make foreach() return a named list/data.frame. E.g.

foo <- list(a = 1, b = 2)
bar <- foreach (x = foo) %do% { x * 2 }

returns list(2, 4). I would want it to return list(a = 2, b = 4).

Plus, is there a way to access the name from within the loop body?

(I'm not interested in a solution which assigns the names after the foreach loop.)

Regards

like image 926
lith Avatar asked Dec 03 '14 16:12

lith


2 Answers

I was using your solution until I needed to use a nested foreach (with the %:% operator). I came up with this:

foo <- list(a = 1, b = 2)
bar <- foreach (x = foo, .final = function(x) setNames(x, names(foo))) %do% {
    x * 2
    }

The trick is to use the .final argument (which is a function applied once at the final result) to set the names. This is nicer because it doesn't use a temporary variable and is overall cleaner. It works with nested lists so that you can preserve the names accross several layers of the structure.

Note that this only works correctly if foreach has the argument .inorder=T (which is the default).

like image 120
asachet Avatar answered Oct 16 '22 03:10

asachet


Thanks for your recommendations. This is what I came up with:

foo <- list(a = 1, b = 2)
bar <- foreach (x = foo, n = names(foo), .combine = c) %do% {
    rv <- list()
    rv[[n]] <- x * 2
    rv
}
like image 4
lith Avatar answered Oct 16 '22 05:10

lith