在R

时间:2018-05-15 19:50:38

标签: r dplyr

我有兴趣根据其索引元素分解重建原始向量。例如,假设我有以下字符串向量:

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

采用the question about matching all occurrences,我们可以将此向量分解为其索引元素配对,如下所示:

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 :(得分:4)

这样的东西
rep(names(dcomp), lengths(dcomp))[order(unlist(dcomp))]

使其成为像

这样的功能
reconstruct <- function(x) rep(names(x), lengths(x))[order(unlist(x))]
dcomp %>% reconstruct()

答案 1 :(得分:3)

我们可以使用stack然后arrange使用data.frame并提取我们需要的列:

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

如果你想摆脱那些因素水平:

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