Инвертирование операции сопоставления в R - PullRequest
0 голосов
/ 15 мая 2018

Я заинтересован в восстановлении исходного вектора на основе его разложения по индексным элементам. Например, предположим, что у меня есть следующий вектор строк:

v <- c( "a", "a", "b", "c", "b", "a", "c" )

Приняв вопрос о сопоставлении всех вхождений , мы можем разложить этот вектор на его пару индекс-элемент следующим образом:

library( tidyverse )
dcomp <- set_names(letters[1:3]) %>% map( ~which(v==.x) )
# $a
# [1] 1 2 6
#
# $b
# [1] 3 5
#
# $c
# [1] 4 7

Я ищу элегантный способ отменить эту операцию и восстановить исходный вектор v из dcomp. Наиболее прямолинейное решение использования цикла требует предварительной инициализации контейнера результатов и не очень хорошо работает с конвейером в стиле dplyr через %>%:

## BAD SOLUTION #1
u <- c()
for( i in names(dcomp) )
  u[ dcomp[[i]] ] <- i
all( u == v )  ## TRUE

Использование purrr::iwalk действительно хорошо играет с трубой %>%, но все равно требует предварительной инициализации u и использования часто наказанного <<- (в противном случае u назначение не видимый вне среды, где формула оценивается).

## BAD SOLUTION #2
u <- c()
dcomp %>% iwalk( ~(u[.x] <<- .y) )
all( u == v )  ## TRUE

Есть ли способ построить результат "на лету", используя заранее заданное отображение элементов на индексы, таким образом, чтобы это хорошо интегрировалось с %>% трубопроводами? Структуру dcomp можно изменять, пока она сохраняет отображение.

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Как насчет чего-то вроде

rep(names(dcomp), lengths(dcomp))[order(unlist(dcomp))]

сделать его функцией как

reconstruct <- function(x) rep(names(x), lengths(x))[order(unlist(x))]
dcomp %>% reconstruct()
0 голосов
/ 15 мая 2018

Мы можем использовать stack, а затем arrange data.frame и извлечь нужный столбец:

stack(dcomp) %>% arrange(values) %>% .$ind

И если вы хотите избавиться от этих уровней факторов:

stack(dcomp) %>% arrange(values) %>% .$ind %>% as.character
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...