通常 data.table 包在这些类型的情况下非常有效。示例如下:
library(data.table)
#> Warning: package 'data.table' was built under R version 4.1.1
df <- fread(text = "snp id a1 a2 code
snp1 an1 A A 0
snp1 an2 A B 1
snp1 an3 B B -1
snp2 an1 A B 1
snp2 an2 A A 0
snp2 an3 B B -1")
dcast(df, id ~ snp, value.var = "code")
#> id snp1 snp2
#> 1: an1 0 1
#> 2: an2 1 0
#> 3: an3 -1 -1
由reprex package (v2.0.1) 于 2021 年 10 月 13 日创建
如果您需要将输出作为矩阵,您可以使用:
cast <- dcast(df, id ~ snp, value.var = "code")
mat <- as.matrix(cast[, -"id"])
rownames(mat) <- cast$id
mat
#> snp1 snp2
#> an1 0 1
#> an2 1 0
#> an3 -1 -1
对于一个 ~3Gb 的文件,您可能希望它运行大约 10 秒:
library(data.table)
#> Warning: package 'data.table' was built under R version 4.1.1
# Setting up larger data
df <- expand.grid(
snp = paste0("snp", 1:10000),
id = paste0("an", 1:10000)
)
df$a1 <- sample(c("A", "B"), nrow(df), replace = TRUE)
df$a2 <- sample(c("A", "B"), nrow(df), replace = TRUE)
df$code <- with(df, dplyr::case_when(
a1 == "A" & a2 == "A" ~ 0,
a1 == "B" & a2 == "B" ~ -1,
TRUE ~ 1
))
setDT(df)
# How big is this data?
format(object.size(df), "Gb")
#> [1] "3 Gb"
# How fast does the function run?
bench::mark(
dcast(df, id ~ snp, value.var = "code")
)
#> Warning: Some expressions had a GC in every iteration; so filtering is disabled.
#> # A tibble: 1 x 6
#> expression min median `itr/sec` mem_alloc
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt>
#> 1 dcast(df, id ~ snp, value.var = "code") 9.32s 9.32s 0.107 6.71GB
#> # ... with 1 more variable: gc/sec <dbl>
由reprex package (v2.0.1) 于 2021-10-13 创建