r - 使用 expand.grid 但保留命名字符值
问题描述
我有一个带有命名字符向量的嵌套列表,我expand.grid()
用来生成每个可能的值。这进展顺利,但我也想保留命名值。
我的结构如下:
a <- list("id1" = c(setNames(1,"Apple"), setNames(2,"Banana")), "id2" = c(setNames(3,"Jam"), setNames(4,"Peanut butter")))
> a
$id1
Apple Banana
1 2
$id2
Jam Peanut butter
3 4
使用expand.grid()
给出以下内容:
> expand.grid(a)
id1 id2
1 1 3
2 2 3
3 1 4
4 2 4
但是,我希望它是:
> a
id1 id2 id1.name id2.name
1 1 3 Apple Jam
2 2 3 Banana Peanut butter
3 1 4 Apple Jam
4 2 4 Banana Peanut butter
有没有办法做到这一点?我目前正在尝试创建一个查找表,然后匹配所有值,但这也被证明是困难的。
解决方案
我们可以使用crossing
.
- 循环
list
命名的vector
-map
- 使用
stack
frombase R
转换命名向量 -> 两列ind/values
data.frame - 适用
crossing
于invoke
- 类似于do.call
frombase R
- 通过调用` data.frame
list
来展平列以创建普通列 - 重命名列(如果需要)
library(dplyr)
library(tidyr)
library(purrr)
library(stringr)
map(a, stack) %>%
invoke(crossing, .)%>%
invoke(data.frame, .) %>%
rename_with(~ str_replace_all(., setNames(c("", ".name"),
c("\\.values", "\\.ind"))), everything())
id1 id1.name id2 id2.name
1 1 Apple 3 Jam
2 1 Apple 4 Peanut butter
3 2 Banana 3 Jam
4 2 Banana 4 Peanut butter
或者另一个选项是expand_grid
通过循环使用list
with ,并使用by 赋值 ( )imap
创建列名,最后重新排序names
list
:=
select
library(stringr)
library(purrr)
library(tidyr)
library(dplyr)
imap_dfc(a, ~ expand_grid(!! .y := .x,
!! str_c(.y, ".name") := names(.x))) %>%
select(matches("^id\\d+$"), everything())
-输出
# A tibble: 4 x 4
id1 id2 id1.name id2.name
<dbl> <dbl> <chr> <chr>
1 1 3 Apple Jam
2 1 3 Banana Peanut butter
3 2 4 Apple Jam
4 2 4 Banana Peanut butter
推荐阅读
- android - Flutter 作为 UIModule
- barcode-scanner - 如何添加 onClickListener 打开条码扫描器?
- c# - 获取用于运行进程的命令
- sql-server - 使用 Azure 数据工厂中的复制数据工具指定要复制的表的顺序以尊重外键
- django - 修改基于类的视图以将数据添加到登录用户
- c - 我该如何继续计算这个函数(f3)的时间复杂度?
- javascript - 为 Gatsby 上的 onRouteUpdate 元素添加样式或类
- c# - 如何在运行时使用 Unity3D 设置撤消/重做系统
- angular - tsconfig 中的路径映射被解释为外部模块
- python - Jupyter 中的这两个 Python Notebook 有什么区别?