Home > database >  Invert a list of (key, values) pairs
Invert a list of (key, values) pairs

Time:03-17

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"
  •  Tags:  
  • r
  • Related