I want to invert a named list of (key,values)
pairs into a named list of (value,key)
pairs. It's safe to assume that the values are unique across keys but the vectors are of different lengths.
I came up with a solution that uses purrr::map
and then purrr::flatten
.
Is there a more elegant solution?
library("tidyverse")
key_values_list <- list(
a = c("x", "y"),
b = c("A", "B", "C")
)
myinvert <- function(key, values) {
setNames(rep_along(values, key), values)
}
value_key_pairs <-
names(key_values_list) %>%
map(
~ myinvert(., key_values_list[[.]])
) %>%
flatten()
value_key_pairs
#> $x
#> [1] "a"
#>
#> $y
#> [1] "a"
#>
#> $A
#> [1] "b"
#>
#> $B
#> [1] "b"
#>
#> $C
#> [1] "b"
Created on 2022-03-16 by the reprex package (v2.0.1)
CodePudding user response:
We may use stack
with split
in base R
with(stack(key_values_list), split(as.character(ind), values))
If the order needs to be maintained
with(stack(key_values_list), split(as.character(ind),
factor(values, levels = unique(values))))
Or with rep/lengths/unlist
setNames(as.list(rep(names(key_values_list),
lengths(key_values_list))), unlist(key_values_list))
CodePudding user response:
In your case, this does what you want:
> library(hash)
> as.list(invert(hash(key_values_list)))
$x
[1] "a"
$y
[1] "a"
$A
[1] "b"
$B
[1] "b"
$C
[1] "b"