我有一个名为list1
的矩阵列表,其结构如下:
$ENSLAFT00000000003
start end
[1,] 360 360
[2,] 394 394
$ENSLAFT00000000011
start end
[1,] 15 15
$ENSLAFT00000000020
start end
[1,] 45 45
$ENSLAFT00000000023
start end
$ENSLAFT00000000024
start end
[1,] 13 13
[2,] 369 369
[3,] 602 602
[4,] 775 775
[5,] 983 983
[6,] 1200 1200
[7,] 1491 1491
有些项目是空的,但我想将此列表转换为具有两列和以下结构的data.frame:
ID pos
ENSLAFT00000000003 360
ENSLAFT00000000003 394
ENSLAFT00000000011 15
ENSLAFT00000000020 45
ENSLAFT00000000024 13
ENSLAFT00000000024 369
ENSLAFT00000000024 602
ENSLAFT00000000024 775
ENSLAFT00000000024 983
ENSLAFT00000000024 1200
ENSLAFT00000000024 1491
ENSLAFT00000000023在输出中被省略,因为它在初始列表中是一个空矩阵。
我可以通过使用在一定程度上获得所需的结构,但不需要保留行名标识
as.data.frame(do.call(rbind, e)[,1])
但我仍然缺乏保留所需的行名。
你对在R中进行这种数据转换有什么建议吗?
向致以最良好的问候
我们通过在list
和stack
上循环提取'start'元素,将其提取为两列数据帧
out <- stack(lapply(lst1, (x) {
st <- x[,"start"]
if(length(st) == 0) st <- NA_real_
st
}))[2:1]
names(out) <- c("ID", "pos")
这里有一个tidyverse
选项:
library(tidyverse)
map(list1, ~ select(as.data.frame(.x), start)) %>%
enframe %>%
unnest(value,keep_empty = TRUE)
输出
name start
<chr> <dbl>
1 ENSLAFT00000000003 360
2 ENSLAFT00000000003 360
3 ENSLAFT00000000011 15
4 ENSLAFT00000000023 NA
数据
list1 <- list(ENSLAFT00000000003 = structure(c(360, 360, 394, 394), .Dim = c(2L,
2L), .Dimnames = list(NULL, c("start", "end"))), ENSLAFT00000000011 = structure(c(15,
15), .Dim = 1:2, .Dimnames = list(NULL, c("start", "end"))),
ENSLAFT00000000023 = structure(logical(0), .Dim = c(0L, 2L
), .Dimnames = list(NULL, c("start", "end"))))
另一个可能的解决方案,基于purrr::imap_dfr
(我正在使用@AndrewGillreath Brown的数据,我感谢他(:
library(tidyverse)
imap_dfr(l, ~ bind_cols(ID = .y, pos = if (nrow(.x) == 0) NA else .x[,"start"]))
#> # A tibble: 4 × 2
#> ID pos
#> <chr> <dbl>
#> 1 ENSLAFT00000000003 360
#> 2 ENSLAFT00000000003 360
#> 3 ENSLAFT00000000011 15
#> 4 ENSLAFT00000000023 NA