将数字向量列表转换为数据框并按顺序写入数字

Convert list of numeric vectors into data frame and write number in sequence

如何将列表列表转换为保留列表名称的单个数据框,然后添加序列号。

str(data) 给我这个:

List of 230
 $ data_1  : num [1:19, 1:2] 0.0204 0.0516 0.0924 0.1424 0.2044 ...
 $ data_14 : num [1:19, 1:2] 0.006 0.0144 0.0272 0.0456 0.0712 ...
 $ data_2  : num [1:19, 1:2] 0.0292 0.0736 0.1316 0.202 0.286 ...
 $ data_27 : num [1:19, 1:2] 0.0056 0.0136 0.024 0.0384 0.0572 ...
 $ data_46 : num [1:19, 1:2] 0.0164 0.0408 0.0716 0.11 0.1588 ...
 $ data_510: num [1:19, 1:2] 0.0128 0.034 0.0652 0.1112 0.1756 ...
 $ data_13  : num [1:19, 1:2] 0.0064 0.0136 0.022 0.0332 0.046 ...
 $ data_19  : num [1:19, 1:2] 0.0036 0.0096 0.0224 0.0444 0.0776 ...
 $ data_080: num [1:19, 1:2] 0.0056 0.0132 0.0228 0.0356 0.052 ...
 $ data_15 : num [1:19, 1:2] 0.0028 0.0068 0.0116 0.0172 0.0244 ...
 $ data_18 : num [1:19, 1:2] 0.0008 0.0012 0.0024 0.0032 0.0044 0.0064 0.0096 0.014 0.02 0.0268 ...
 $ data_3  : num [1:19, 1:2] 0.0124 0.0308 0.0576 0.0932 0.1384 ...
 $ data_33 : num [1:19, 1:2] 0.0036 0.0084 0.016 0.0252 0.0372 ...
 $ data_500: num [1:19, 1:2] 0.004 0.0096 0.0196 0.0372 0.0648 ...
 $ data_015 : num [1:19, 1:2] 0.0072 0.0172 0.03 0.0456 0.064 ...
 $ data_02  : num [1:19, 1:2] 0.0132 0.0296 0.0484 0.0696 0.0936 ...
 $ data_04  : num [1:19, 1:2] 0.0072 0.0192 0.038 0.0692 0.1132 ...
 $ data_37  : num [1:19, 1:2] 0.0056 0.014 0.0252 0.0388 0.0552 ...
 $ data_4   : num [1:19, 1:2] 0.0072 0.0188 0.0352 0.056 0.0812 ...
 $ data_550 : num [1:19, 1:2] 0.004 0.0104 0.02 0.032 0.048 ...

...列表重复 2 到 30 次

我要找的是这样的:

ID  Area    Size    Interval
data_1  0.0204  0.1     1
data_1  0.0516  0.15    1
data_1  0.0924  0.2     1
data_1  0.1424  0.25    1
data_14 0.006   0.1     1
data_14 0.0144  0.15    1
data_14 0.0272  0.2     1
data_14 0.0456  0.25    1
data_1  0.0204  0.1     1
data_1  0.0516  0.15    1
data_1  0.0924  0.2     1
data_1  0.1424  0.25    1
data_14 0.006   0.1     1
data_14 0.0144  0.15    1
data_14 0.0272  0.2     1
data_14 0.0456  0.25    1
data_1  0.0254  0.1     2
data_1  0.0566  0.15    2
data_1  0.0974  0.2     2
data_1  0.1474  0.25    2
data_14 0.011   0.1     2
data_14 0.0194  0.15    2
data_14 0.0322  0.2     2
data_14 0.0506  0.25    2
data_1  0.0254  0.1     2
data_1  0.0566  0.15    2
data_1  0.0974  0.2     2
data_1  0.1474  0.25    2
data_14 0.011   0.1     2
data_14 0.0194  0.15    2
data_14 0.0322  0.2     2
data_14 0.0506  0.25    2

我试过lapply(data, data.frame)do.call(rbind.data.frame, data)

但是并没有完全按照我想要的方式工作...

我们可以使用data.table。循环 list,转换为 data.frame,使用 rbindlist 垂直绑定 list 中的 data.frames(选项 idcol=TRUE 确保基于 listnames 创建单独的列。我们可以使用 base R 中的 rleave 创建一个 'Seq' 列对于不相邻的重复“.id”值。

library(data.table)
rbindlist(lapply(data, as.data.frame), idcol=TRUE)[, Seq :=inverse.rle(within.list(rle(.id), 
                 values <- ave(values, values, FUN=seq_along)))][]

或者用dplyr,我们用bind_rows做垂直绑定,根据相邻的'ID'值是否相同,创建一个分组变量('grp')没有。

library(dplyr)
dM1 <- lapply(data, as.data.frame) %>% 
                bind_rows(., .id = "ID") %>%
                mutate(grp = cumsum(ID!= lag(ID, default="999")))

我们得到 'ID' 和 'grp' 的 unique 行选择上面的数据,按 'ID' 分组,用 row_number() 创建一个序列列并做right_join.

dM1 %>%
   select(ID, grp) %>% 
   unique() %>% 
   group_by(ID) %>%
   mutate(Seq = row_number())  %>%
   right_join(., dM1)  %>%
   select(-grp)

更新

或者更简单的方法是将序列按 listnames 分组(即 'data'),将 names 更改为 paste使用原始名称对序列进行排序,通过使用 lapply 遍历 list 将矩阵的 list 转换为 data.frames 的 list,绑定行 (bind_rows) 将 .idseparate 指定为两个 'ID' 列。

library(dplyr)
library(tidyr)
names(data) <- paste(names(data), ave(names(data), names(data),
                     FUN= seq_along), sep=",")

lapply(data, as.data.frame) %>%
        bind_rows(., .id = "ID") %>%
        separate(ID, into = c("ID", "Seq"), sep=",")