将矩阵列表转换为数据框,其中行名称为列表名称。

4
我有一个名为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

这个列表中有一些项目是空的,但我想将它转换为一个有两列的数据框,结构如下:

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中执行此数据转换的建议吗?

最好的问候

3个回答

5

我们通过循环遍历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")

你好@akrun,我有一个问题,\(x)是指“function(x)”吗? - Alexis
1
@Alexis 是的,它是最近 R 版本中 base R 中的一种简洁选项。 - akrun

3

这是一个 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"))))

1
我猜你需要将那些行数为0的元素改为NA。 - akrun
1
我的意思是 map(lst1, ~ .x[, "start"]) %>% enframe %>% unnest(value, keep_empty = TRUE) - akrun

3

另一种可能的解决方案是基于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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接