有两种可能的方法,它们仅在操作序列方面有所不同:
- 将列表中的所有数据框单独从长格式转换为宽格式,并使用
rbind()
匹配列。
rbind()
所有长格式的数据框,然后再转换为宽格式。
这两种方法都需要以某种方式包含 bundle
。
为了完整起见,这里提供了使用 data.table
实现第二种方法的不同实现。
library(data.table)
library(magrittr)
d2 %>%
rbindlist(idcol = "bid") %>%
setDT(bundle)[, bid := .I][., on = "bid"] %>%
dcast(., bundle ~ id, fill = 0)
bundle 35 211 220 381 394 926 930 1109 1462
1: 284993459 0.2 0.1 0.2 0.0 0.0 0.0 0.0 0.2 0.2
2: 511310430 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.5
3: 1034630958 0.0 0.0 0.0 0.3 0.0 0.3 0.2 0.0 0.3
4: 1235581326 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.5
这里,管道符号仅用于可视化函数调用的顺序。使用 data.table
的链式操作语句更加简洁:
library(data.table) # library(magrittr) not required
setDT(bundle)[, bid := .I][
rbindlist(d2, id = "bid"), on = "bid"][, dcast(.SD, bundle ~ id, fill = 0)]
或者
library(data.table)
dcast(setDT(bundle)[, bid := .I][
rbindlist(d2, id = "bid"), on = "bid"], bundle ~ id, fill = 0)
另一种变体是在调用rbindlist()
之前重命名列表元素,这将使用名称创建idcol
:
library(data.table)
library(magrittr)
d2 %>%
# rename list elements
setNames(bundle$bundle) %>%
# bind row-wise into large data.table, create id column from element names
rbindlist(idcol = "bundle") %>%
# convert bundle from character to factor to maintain original order
.[, bundle := forcats::fct_inorder(bundle)] %>%
# reshape from long to wide format
dcast(., bundle ~ id, fill = 0)
bundle 35 211 220 381 394 926 930 1109 1462
1: 284993459 0.2 0.1 0.2 0.0 0.0 0.0 0.0 0.2 0.2
2: 511310430 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.5
3: 1034630958 0.0 0.0 0.0 0.3 0.0 0.3 0.2 0.0 0.3
4: 1235581326 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.5
请注意,到目前为止呈现的变体已经跳过了空数据框,该数据框属于
bundle
1048768805(同样是
Moody_Mudskipper和
chinsoon12的答案)。
为了在最终结果中保留空数据框,必须更改连接的顺序,以保留
bundle
的所有行:
library(data.table)
dcast(
rbindlist(d2, id = "bid")[setDT(bundle)[, bid := .I], on = "bid"],
bundle ~ id, fill = 0
)[, "NA" := NULL][]
bundle 35 211 220 381 394 926 930 1109 1462
1: 284993459 0.2 0.1 0.2 0.0 0.0 0.0 0.0 0.2 0.2
2: 511310430 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.5
3: 1034630958 0.0 0.0 0.0 0.3 0.0 0.3 0.2 0.0 0.3
4: 1048768805 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
5: 1235581326 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.5
或者,如果要保留bundle
的确切顺序:
library(data.table)
dcast(
rbindlist(d2, id = "bid")[setDT(bundle)[, bid := .I], on = "bid"],
bid + bundle ~ id, fill = 0
)[, c("bid", "NA") := NULL][]
bundle 35 211 220 381 394 926 930 1109 1462
1: 284993459 0.2 0.1 0.2 0.0 0.0 0.0 0.0 0.2 0.2
2: 1048768805 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3: 511310430 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.5
4: 1034630958 0.0 0.0 0.0 0.3 0.0 0.3 0.2 0.0 0.3
5: 1235581326 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.5
bundle
的长度是否等于列表的长度? - LAP