r - 对整数矩阵的列表列进行子集化
问题描述
背景
我让自己陷入了这样一种情况,即 tibble/dataframe 中的一列由一个整数矩阵列表组成,这些矩阵有零行或多行,正好有 2 列。此列恰好是stringr::str_locate_all()
调用的输出,所以我希望这是一个常见的场景。
我想做的是只选择整数矩阵的一列,然后取消嵌套数据框,但我对如何正确执行此操作感到困惑。
例子
这是一个示例(我必须手动创建它,因为dpasta()
它似乎不适用于列表列标题)。无论如何,我的出发点是tibble mydf:
library(tidyverse)
m1 <- matrix( c(761,784), nrow=1,ncol=2, dimnames = list(c(),c("start","end")) )
m2 <- matrix( integer(0), nrow=0,ncol=2, dimnames = list(c(),c("start","end")) )
m3 <- matrix( c(1001,2300,1010,2310), nrow=2,ncol=2, dimnames = list(c(),c("start","end")) )
mydf <- tibble( item = c("a","b","c"), pos = list(m1,m2,m3))
下面是 rstudio 查看器中的样子。这有点误导,因为它表明 pos 行只是整数向量。它们实际上是 nx2 矩阵,没有任何线索表明它更复杂。这让我有些困惑,但现在已经无关紧要了。
我想要做的是最终得到一个未嵌套的小标题,其中选择了第一列“开始”。所需的输出将如下所示(取消嵌套后):
mydf_desired <- tibble( item = c("a","c","c"), start_pos = c(761,1001,2300))
请注意, mydf 中的第一行在其 pos 矩阵中只有一行,因此它在所需结果中有一行。item="b" 的行有一个 0x2 矩阵,所以它不会出现(但如果它也显示为 NA 就可以了)。item="c" 的行在 pos 矩阵中有两行,因此它在所需结果中有两行。
我试过的
这看起来很简单,我之前没有嵌套过列表列。这里唯一的转折是我必须先选择“开始”列,然后再取消嵌套,对吗?我只是map
将 pos 列表列添加到 [,1] 以选择第一列(“开始”列)。然后它应该是一个取消嵌套的问题......
mydf_desired <- mydf %>%
mutate(start_pos = map(pos, ~ .[,1])) %>%
unnest()
#> Error in vec_rbind(!!!x, .ptype = ptype): Internal error in `vec_assign()`: `value` should have been recycled to fit `x`.
#> Warning: `cols` is now required.
#> Please use `cols = c(pos, start_pos)`
不知道“ value should have been recycled to fit x
”实际上是什么意思,但它也给了我一个关于不给 cols in 的警告unnest()
。现在怀疑是关于我所给予的东西unnest()
。
如果我省略unnest()
我不会得到那个错误......
mydf_desired <- mydf %>%
mutate(start_pos = map(pos, ~ .[,1]))
输出看起来像这样......
那种看起来不错,我注意到 item=b of 仍然有一个 pos 条目integer(0)
。但即使我省略了该行,当我尝试unnest()
.
这就是我难过的地方。为什么我不能只用unnest()
这个 tibble?错误的含义是什么value should have been recycled to fit x
?
解决方案
一种选择是filter
行,然后map
在list
元素上并从 中提取列matrix
,然后使用unnest_longer
library(dplyr)
library(purrr)
mydf %>%
filter(lengths(pos) > 0) %>%
transmute(item, start_pos = map(pos, ~ as.vector(.x[,1]))) %>%
unnest_longer(c(start_pos))
# A tibble: 3 x 2
# item start_pos
# <chr> <dbl>
#1 a 761
#2 c 1001
#3 c 2300
另外,可以避免这filter
一步,如果我们转换为tibble
mydf %>%
transmute(item, pos = map(pos, ~ .x[,1] %>%
tibble(start_pos = .))) %>%
unnest(c(pos))
推荐阅读
- java - Wiremock - 自动配置不加载存根
- sql-server - 如何使用来自 PowerBI 报表服务器的 URL 访问将 SSRS 报表导出为 PDF?
- c++ - 如何使用 glVertexAttribPointer() 添加非数组值
- reactjs - 动态引用 Firestore 文档
- python - 进程如何获取python中全局变量的当前值?
- logstash-grok - SSSD 日志的 Grok 模式
- c# - 根据之前的 appsettings 文件加载自定义 appsettings 文件
- ajax - 在 AjaxLink 中一个接一个地调用几个不同的 JavaScript
- python - Django 中的模板太多
- eclipse - 如何防止 Eclipse 下载 Maven 索引?