Сортування рядків у data.table у порядку зменшення за рядковим ключем `порядком (-x, v) 'дає помилку на data.table 1.9.4 або раніше


125

Скажімо , у мене є такі data.tableв R:

  library(data.table)
  DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)

Я хочу замовити його у двох стовпцях (скажімо стовпці xта v). Я використав це:

 DT[order(x,v)] # sorts first by x then by v (both in ascending order)

Але тепер я хочу сортувати його за x(у порядку зменшення) та мати такий код:

  DT[order(-x)] #Error in -x : invalid argument to unary operator

Тому я думаю, що ця помилка пов’язана з тим, що class(DT$x)=character. Чи можете ви дати мені якусь пропозицію для вирішення цього питання?

Я знаю, що можу використовувати DT[order(x,decreasing=TRUE)], але хочу знати синтаксис для сортування за кількома стовпцями, використовуючи обидва способи (деякі зменшуючи, деякі збільшуючи) одночасно.

Зауважте, що якщо ви використовуєте DT[order(-y,v)]результат, це нормально, але якщо ви використовуєте DT[order(-x,v)], є помилка. Отже, моє запитання: як вирішити цю помилку?


6
Цікаве питання, але якщо ви працюєте з великими наборами даних, ви, ймовірно, повинні встановлювати ключі для своїх таблиць даних. Клавіші розміщують ваші дані в порядку, який максимально збільшує подальшу індексацію, підмножини, агрегацію за групами тощо. Це може бути не кращим форматом для друку даних, але це часто невелика ціна, щоб заплатити за швидкість, яку вона набере. .
Josh O'Brien

Однак мені здається, що DT[order(-x)]це не рівнозначне твердження setorder(DT, -x)тому, що setorder()насправді діє на DTтой час, коли інший цього не робить. Еквівалентними висловлюваннями будуть DT <- DT [order (-x)] setorder (DT, -x) Я дуже новачок у R, тому будь ласка, виправте, якщо я помиляюся.
jeromeResearch

@jerome Ви маєте рацію. Панкіл не сказав, що вони рівноцінні, тому я гадаю, що це добре.
Франк

1
Я погоджуюся з @smci, що редагування заголовка має сенс тут, хоча я б змінив його, щоб вказати, що це питання більше не стосується, наприклад, додавши до заголовка "в data.table 1.9.4 або раніше", щоб люди не стали продовжуйте посадку тут від Google, очікуючи чогось іншого. Я зробив це з одним із моїх запитань stackoverflow.com/questions/30035939/…
Френк

1
Несторг, не відмовляйтеся від нового заголовка, якщо ви не зможете його покращити. "сортувати рядки в data.table" майже нічого не говорив, що базовий функціонал був для іонків. У заголовку потрібно згадати фактичну проблему (декілька клавіш, де одна - наказ decr). Також важливо, щоб це було відомим випуском 1.9.4 і раніше і більше не є проблемою.
smci

Відповіді:


144

Оновлення

data.table v1.9.6 + тепер підтримує оригінальну спробу OP, і наступна відповідь більше не потрібна.


Можна використовувати DT[order(-rank(x), y)].

   x y v
1: c 1 7
2: c 3 8
3: c 6 9
4: b 1 1
5: b 3 2
6: b 6 3
7: a 1 4
8: a 3 5
9: a 6 6

1
Як зазначає @PankilShah нижче, це було виправлено вже деякий час, і оригінальний підхід ОП зараз працює як очікувалося. Я не міг знайти фіксацію, оскільки вона була зафіксована на рівні С і не знаю, що шукати.
MichaelChirico

1
Класно, дякую. Навряд чи хтось тут опиниться ... але з іншого боку, я сам опинився тут, гуляючи щось неясно пов'язане.
MichaelChirico

@MichaelChirico насправді я регулярно отримую голоси за цю відповідь, тому я дуже радий, що ти це вказав. Я на насправді не data.table користувача і не йти в ногу з його розвитком.
Метью Плорд

Це дуже корисно вказати фактичний номер версії (1.9.6?), Так що ми не повинні йти полювати в архівах NEWS.md .
smci

23

Ви можете використовувати лише -числові записи, тож ви можете зменшувати та заперечувати ті, що потрібно, у порядку збільшення:

DT[order(x,-v,decreasing=TRUE),]
      x y v
 [1,] c 1 7
 [2,] c 3 8
 [3,] c 6 9
 [4,] b 1 1
 [5,] b 3 2
 [6,] b 6 3
 [7,] a 1 4
 [8,] a 3 5
 [9,] a 6 6

3
Мені це подобається, якщо у вас немає двох characterстовпців і ви хочете сортувати один збільшуючий, а другий зменшуючий.
Меттью Плорд

1
@mplourde Я думаю, що ви можете поєднати своє рішення з цим, щоб вирішити поставлену проблему. Наприклад, ви можете поставити: з DT[order(x,-rank(w),decreasing=TRUE)]огляду на це xі wє обома стовпцями символів. Дякую!
nhern121

17

DT[order(-x)]працює як очікувалося. Я маю data.table версії 1.9.4. Можливо, це було виправлено в останній версії.
Також я пропоную setorder(DT, -x)синтаксис відповідно до набору * команд типу setnames,setkey

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.