Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

One-To-One apply/map in R operations

I’ve got 3 tibbles in a list that I would like to add a column, for each, with a different value. I found it struggling to do this apart from using the usual for loop (granted, for may well be the best solution in this use case, but I am curious if there’s a clever solution).

library(tibble)
library(dplyr)

t1 <- tibble(a=1:10, b=2:11, c=3:12)
t2 <- tibble(a=1:10, b=2:11, c=3:12)
t3 <- tibble(a=1:10, b=2:11, c=3:12)
tlist <- list(t1, t2, t3)

names <- c("A", "B", "C")

The result I wanted to achieve would be the same as that we do dplyr::mutate on each tibble to add that extra column with values in names respectively; to illustrate:

t1 %>% mutate(name=names[1])
t2 %>% mutate(name=names[2])
t3 %>% mutate(name=names[3])

I’ve tried lapply, sapply, and mapply (and some combinations of either two of them), or purrr::map, I couldn’t see a way of applying mutate action of a single value on a single tibble (i.e., one-to-one apply/map). Python has zip which sometimes creates a pair of values that we can easily access in apply functions, but we don’t have that facility in R.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

A piece of pusedo-ish code in R (which mimics what zip in Python would be like):

args <- pair(tlist, names)

add.col <- function(arg.pair) -> {
    arg.pair[[1]] %>% mutate(name=arg.pair[[2]])
}

res <- args %>% lapply(add.col)

Note that apply functions do not take in Pair object (a utility from stats package).

It’s very likely there’s blind spot for me as I became increasingly obsessed with apply; is there clever way to do this one-to-one mapping?

>Solution :

Use map2:

library(purrr)
library(dplyr)
map2(tlist, names, 
     ~ .x %>% 
       mutate(name = .y))

Or in base R with Map:

Map(function(x, y) transform(x, name = y), tlist, names)

output:

[[1]]
# A tibble: 10 × 4
       a     b     c name 
   <int> <int> <int> <chr>
 1     1     2     3 A    
 2     2     3     4 A    
 3     3     4     5 A    
 4     4     5     6 A    
 5     5     6     7 A    
 6     6     7     8 A    
 7     7     8     9 A    
 8     8     9    10 A    
 9     9    10    11 A    
10    10    11    12 A    

[[2]]
# A tibble: 10 × 4
       a     b     c name 
   <int> <int> <int> <chr>
 1     1     2     3 B    
 2     2     3     4 B    
 3     3     4     5 B    
 4     4     5     6 B    
 5     5     6     7 B    
 6     6     7     8 B    
 7     7     8     9 B    
 8     8     9    10 B    
 9     9    10    11 B    
10    10    11    12 B    

[[3]]
# A tibble: 10 × 4
       a     b     c name 
   <int> <int> <int> <chr>
 1     1     2     3 C    
 2     2     3     4 C    
 3     3     4     5 C    
 4     4     5     6 C    
 5     5     6     7 C    
 6     6     7     8 C    
 7     7     8     9 C    
 8     8     9    10 C    
 9     9    10    11 C    
10    10    11    12 C   
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading