#r #data.table
#r #data.table
Вопрос:
Я хочу изменить порядок строк в моей таблице в соответствии с символьной переменной ( stage
в моем примере). Если я сначала сохраню желаемый order ( order(dt1$stage)
) в переменную, а затем применю его как dt1[myorder, stage]
— он работает нормально. Но когда я пытаюсь сделать то же самое встроенное, например dt1[order(dt1$stage), ]
, порядок отличается! Должно быть, что-то очень простое, чего мне не хватает…
dt1 <- fread('
id stage pos
1 I 1
2 II 2
3 III 5
4 IV 6
5 IIa 3
6 IIb 7
7 IIIa 8
8 IIIb 4
9 IVa 9
10 IVb 10')
sort(dt1$stage) # OK
# I II IIa IIb III IIIa IIIb IV IVa IVb
myorder <- order(dt1$stage)
dt1[myorder , stage] # OK
# I II IIa IIb III IIIa IIIb IV IVa IVb
dt1[order(dt1$stage), stage] # different!
# I II III IIIa IIIb IIa IIb IV IVa IVb
Ответ №1:
Он выполняет a fast
order
вместо base::order
. Согласно ?data.table::order
Обратите внимание, что запросы типа x[order(.)] оптимизированы внутренне для использования быстрого порядка data.table.
Также обратите внимание, что data.table всегда переупорядочивает в «C-locale» (см. Подробности). Для сортировки по языку сеанса используйте x[base::order(.)] .
data.table реализует свой собственный быстрый порядок на основе radix.
data.table всегда переупорядочивает в «C-locale». Как следствие, порядок может отличаться от порядка, полученного с помощью base::order . Например, в английских языках сортировка чувствительна к регистру в C-locale. Таким образом, сортировка c(«c», «a», «B») возвращает c(«B», «a», «c») в data.table, но c(«a», «B», «c») в base::ord
Если мы хотим реплицировать sort
from base
, используйте base::order
dt1[base::order(stage)]$stage
#[1] "I" "II" "IIa" "IIb" "III" "IIIa" "IIIb" "IV" "IVa" "IVb"
Комментарии:
1. большое спасибо, теперь все ясно! Итак, если бы я хотел изменить порядок всей таблицы, вместо
setorder(dt1, stage)
я должен использоватьdt1 <- dt1[base::order(stage),]
, верно?2. @VasilyA да, но это может быть медленным по сравнению с
setorder
большими наборами данных