I am trying to take a column of index vectors and splice them into a pluck()
call to get the value at those indexes. It works fine if I do that in a map()
call at the top level, but it does not recognize .x
argument when the map()
is called inside of a mutate()
. Can anyone explain why? Is there a syntax I am missing?
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(purrr)
lst <-
list(a=1, b=list(c=2, d=3))
str(lst)
#> List of 2
#> $ a: num 1
#> $ b:List of 2
#> ..$ c: num 2
#> ..$ d: num 3
#;; Note what is at index c(2L, 2L)
lst[[c(2L, 2L)]]
#> [1] 3
#;; Put that index in a dataframe column.
idx_df <-
tibble(idx=list(c(2L, 2L)))
idx_df
#> # A tibble: 1 × 1
#> idx
#> <list>
#> 1 <int [2]>
#;; This does not work, but I expect it to, as I believe it should work
#;; analagously to what is below.
tryCatch({
idx_df |>
mutate(val = map_dbl(idx, ~ pluck(lst, !!!.x)))
}
, error=\(e) e)
#> <simpleError in quos(..., .ignore_empty = "all"): object '.x' not found>
#;; This works, but I should be able to do this in a mutate call.
idx_df$val <-
map_dbl(idx_df$idx, ~ pluck(lst, !!!.x))
idx_df
#> # A tibble: 1 × 2
#> idx val
#> <list> <dbl>
#> 1 <int [2]> 3
Created on 2023-05-09 with reprex v2.0.2
As highlighted, problem seems to be when !!!
is evaluated. As a simple workaround, you could create an interim function so that !!!
isn't evaluated until the function is called:
library(dplyr)
library(purrr)
lst <-
list(a=1, b=list(c=2, d=3))
idx_df <-
tibble(idx=list(c(2L, 2L)))
pluck_loc <- function(x) {
pluck(lst, !!!x)
}
idx_df |>
mutate(val = map_dbl(idx, pluck_loc))
#> # A tibble: 1 × 2
#> idx val
#> <list> <dbl>
#> 1 <int [2]> 3