如何在R中优雅反转索引-元素分解,重建原始向量?
嘿,我有几个超适配管道、不用预初始化容器的优雅解法,帮你从索引-元素映射重建原始向量,完全避开循环和讨厌的<<-赋值:
方法1:用
tibble展开+排序提取(最直观) 核心思路是把每个元素和对应的索引展开成结构化的数据框,按索引排序后提取元素列,全程用管道串起来,非常流畅:
library(tidyverse) # 原始向量 v <- c( "a", "a", "b", "c", "b", "a", "c" ) # 分解得到索引-元素映射 dcomp <- set_names(letters[1:3]) %>% map( ~which(v==.x) ) # 重建原始向量 v_rebuilt <- dcomp %>% # 遍历映射,把索引和对应元素组合成tibble imap_dfr(~tibble(idx = .x, val = .y)) %>% # 按索引排序,还原原始顺序 arrange(idx) %>% # 提取元素列得到最终向量 pull(val) # 验证结果一致 all.equal(v_rebuilt, v) # 返回 TRUE
方法2:用重复+索引排序(更简洁)
如果喜欢更紧凑的代码,可以通过重复元素值、再按索引顺序重新排列的方式实现:
v_rebuilt2 <- dcomp %>% # 把每个元素值重复对应索引的次数 map2(names(.), ~rep(.y, length(.x))) %>% # 展开成一维字符向量 flatten_chr() %>% # 按原始索引的顺序重新排列 `[`(order(unlist(dcomp))) all.equal(v_rebuilt2, v) # 返回 TRUE
方法3:先调整dcomp为长格式(灵活性更高)
如果愿意提前调整dcomp的结构,转成长格式的tibble后操作会更直观,后续扩展也方便:
# 先把dcomp转成长格式映射表 dcomp_long <- dcomp %>% enframe(name = "val", value = "idx") %>% unnest(idx) # 重建向量 v_rebuilt3 <- dcomp_long %>% arrange(idx) %>% pull(val) all.equal(v_rebuilt3, v) # 返回 TRUE
这些方法都完全适配%>%管道,不需要预初始化结果容器,也没有使用副作用赋值,代码简洁易读,完美符合你想要的优雅实现~
内容的提问来源于stack exchange,提问作者Artem Sokolov
相关产品推荐
相关产品推荐

