Как сгруппировать по нескольким столбцам и выбрать первое значение с помощью data.table - PullRequest
1 голос
/ 09 апреля 2020

У меня есть следующий код с data.table:

library(data.table)
dat <- structure(list(barcodes = c("scA22_CAACAGCAACAG", "scA22_CAACAGCAACAG", 
"scA22_CAACAGCAACAG", "scA22_CAACAGCAACAG", "scA22_CAACAGCAACAG", 
"scA22_CAACAGCAACAG", "scA22_CAACAGCAACAG", "scA22_TTTTTTTTTTTT"
), gene_name = c("A930037H05Rik", "A930037H05Rik", "A930037H05Rik", 
"A930037H05Rik", "Lgals8", "Lgals8", "Lgals8", "Lgals8"), tsse = c(0.152777777777778, 
0.152777777777778, 0.152777777777778, 0.00192307692307692, 0.055, 
0.0485294117647059, 0.033, 0.0294642857142857)), na.action = structure(integer(0), .Names = character(0)), row.names = c(NA, 
8L), class = "data.frame")

setDT(dat)

dat

Он производит это:

             barcodes     gene_name        tsse
1: scA22_CAACAGCAACAG A930037H05Rik 0.152777778
2: scA22_CAACAGCAACAG A930037H05Rik 0.152777778
3: scA22_CAACAGCAACAG A930037H05Rik 0.152777778
4: scA22_CAACAGCAACAG A930037H05Rik 0.001923077
5: scA22_CAACAGCAACAG        Lgals8 0.055000000
6: scA22_CAACAGCAACAG        Lgals8 0.048529412
7: scA22_CAACAGCAACAG        Lgals8 0.033000000
8: scA22_TTTTTTTTTTTT        Lgals8 0.029464286

Что я хочу сделать, это сгруппировать по c("barcodes", "gene_name") и затем выбрать основано на tsse.

В результате:

             barcodes     gene_name        tsse
1: scA22_CAACAGCAACAG A930037H05Rik 0.152777778
2: scA22_CAACAGCAACAG        Lgals8 0.055000000
3: scA22_TTTTTTTTTTTT        Lgals8 0.029464286

Как этого добиться с помощью data.table. В действительности у меня есть около 300 миллионов линий для производства. Так что мне нужна скорость с data.table.

Ответы [ 3 ]

4 голосов
/ 09 апреля 2020

Кроме того, вы можете установить ключи и выбрать последнюю из каждой группы:

setkey(dat, barcodes, gene_name, tsse)
dat[, tail(.SD, 1), .(barcodes, gene_name)]
#>              barcodes     gene_name       tsse
#> 1: scA22_CAACAGCAACAG A930037H05Rik 0.15277778
#> 2: scA22_CAACAGCAACAG        Lgals8 0.05500000
#> 3: scA22_TTTTTTTTTTTT        Lgals8 0.02946429
2 голосов
/ 09 апреля 2020

Вот еще один вариант:

setorder(dat, barcodes, gene_name, -tsse)
dat[c(TRUE, diff(rleid(barcodes, gene_name))>0L)]

Будет интересно узнать время на фактическом наборе данных

1 голос
/ 09 апреля 2020

Мы можем использовать which.max:

library(data.table)
setDT(dat)[, .SD[which.max(tsse)], .(barcodes, gene_name)]

#             barcodes     gene_name   tsse
#1: scA22_CAACAGCAACAG A930037H05Rik 0.1528
#2: scA22_CAACAGCAACAG        Lgals8 0.0550
#3: scA22_TTTTTTTTTTTT        Lgals8 0.0295
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...