Inferrator
Inferrator

Reputation: 87

Re-creating tibbles within purrr::map

I want to use map to apply a function to each column of a tibble. However, I don't want the tibble columns to be simplified. I could deal with that by re-creating tibbles with one column using imap. However, how do I do that?

Let's use a super-simple function called test to see if it works.

Default behavior: columns simplified to vectors:

test<-function(data){
  data
}

tibble(v1=1:20,v2=100:119) %>% map(test)
$v1
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

$v2
 [1] 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

This can't work because the names need to be quoted:

tibble(v1=1:20,v2=100:119) %>% imap(~test(tibble(.y=.x))) %>% str
List of 2
 $ v1: tibble [20 x 1] (S3: tbl_df/tbl/data.frame)
  ..$ .y: int [1:20] 1 2 3 4 5 6 7 8 9 10 ...
 $ v2: tibble [20 x 1] (S3: tbl_df/tbl/data.frame)
  ..$ .y: int [1:20] 100 101 102 103 104 105 106 107 108 109 ...

So why does this not work?

tibble(v1=1:20,v2=100:119) %>% imap(~test(tibble(!!!(.y)=.x)))
Error: unexpected '=' in "tibble(v1=1:20,v2=100:119) %>% imap(~test(tibble(!!!(.y)="

Upvotes: 2

Views: 299

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389275

You can use setNames :

tibble::tibble(v1=1:20,v2=100:119) %>% purrr::imap(~test(.x) %>% setNames(.y))

#$v1
# A tibble: 20 x 1
#      v1
#   <int>
# 1     1
# 2     2
# 3     3
# 4     4
# 5     5
#...
#...

#$v2
# A tibble: 20 x 1
#      v2
#   <int>
# 1   100
# 2   101
# 3   102
# 4   103
# 5   104
# 6   105
#...
#...

Upvotes: 0

akrun
akrun

Reputation: 887901

We can change the = to assignment operator (:=) and evaluate (!!) the .y on the lhs of :=

library(tibble)
library(purrr)
out <- tibble(v1=1:20,v2=100:119) %>% 
        imap( ~ test(tibble(!!.y := .x)))

-output

str(out)
#List of 2
# $ v1: tibble [20 × 1] (S3: tbl_df/tbl/data.frame)
#  ..$ v1: int [1:20] 1 2 3 4 5 6 7 8 9 10 ...
# $ v2: tibble [20 × 1] (S3: tbl_df/tbl/data.frame)
#  ..$ v2: int [1:20] 100 101 102 103 104 105 106 107 108 109 ...

Upvotes: 1

Related Questions