බහු තීරු (ය) මගින් දත්ත රාමුවක් වර්ග කරන්නේ කෙසේද


1333

මට දත්ත තීරු කිහිපයක් තීරු අනුව වර්ග කිරීමට අවශ්‍යයි. උදාහරණයක් ලෙස, පහත දැක්වෙන දත්ත රාමුව සමඟ මම තීරුව අනුව z( බැසයාම ) පසුව තීරුව අනුව b(නැගීම) වර්ග කිරීමට කැමැත්තෙමි :

dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"), 
      levels = c("Low", "Med", "Hi"), ordered = TRUE),
      x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
      z = c(1, 1, 1, 2))
dd
    b x y z
1  Hi A 8 1
2 Med D 3 1
3  Hi A 9 1
4 Low C 9 2

Answers:


1640

order()ඇඩෝන මෙවලම් වෙත යොමුවීමකින් තොරව ඔබට සෘජුවම ශ්‍රිතය භාවිතා කළ හැකිය - example(order)කේතයේ ඉහළ සිටම උපක්‍රමයක් භාවිතා කරන මෙම සරල පිළිතුර බලන්න :

R> dd[with(dd, order(-z, b)), ]
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1

අවුරුදු 2+ කට පසුව සංස්කරණය කරන්න: තීරු දර්ශකය අනුව මෙය කරන්නේ කෙසේදැයි විමසන ලදි. පිළිතුර නම් order()ශ්‍රිතයට අපේක්ෂිත වර්ග කිරීමේ තීරුව (ය) සරලව යැවීමයි :

R> dd[order(-dd[,4], dd[,1]), ]
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1
R> 

තීරුවේ නම භාවිතා කරනවාට වඩා (සහ with()පහසු / සෘජු ප්‍රවේශය සඳහා).


Ir ඩර්ක් එඩෙල්බුටෙල් මෙට්‍රික්ස් සඳහා සමාන සරල ක්‍රමයක් තිබේද?
ජෝටා

14
එකම ආකාරයකින් වැඩ කළ යුතු නමුත් ඔබට භාවිතා කළ නොහැක with. M <- matrix(c(1,2,2,2,3,6,4,5), 4, 2, byrow=FALSE, dimnames=list(NULL, c("a","b")))අනුකෘතියක් නිර්මාණය කිරීමට උත්සාහ කරන්න M, ඉන්පසු M[order(M[,"a"],-M[,"b"]),]එය තීරු දෙකකින් ඇණවුම් කිරීමට භාවිතා කරන්න.
ඩර්ක් එඩෙල්බුටෙල්

4
ප්‍රමාණවත් තරම් පහසුය :, dd[ order(-dd[,4], dd[,1]), ]නමුත් withනම මත පදනම් වූ උප කුලක සඳහා භාවිතා කළ නොහැක .
ඩර්ක් එඩෙල්බුටෙල්

18
දෙවන උදාහරණය ක්‍රියාත්මක කිරීමේදී මට “අවලංගු ක්‍රියාකරුට අවලංගු තර්කයක්” තිබේ.
නියපොතු

22
ඔබ අක්ෂර තීරුවක් සමඟ us ණ භාවිතා කරන විට "අවලංගු ක්‍රියාකරුට වලංගු නොවන තර්කය" දෝෂය ඇතිවේ. xtfrmඋදාහරණයක් ලෙස තීරුව ඔතා එය විසඳන්න dd[ order(-xtfrm(dd[,4]), dd[,1]), ].
රිචී කපු

485

ඔබේ තේරීම්

  • order සිට base
  • arrange සිට dplyr
  • setorderසහ setordervසිටdata.table
  • arrange සිට plyr
  • sort සිට taRifx
  • orderBy සිට doBy
  • sortData සිට Deducer

යැපීම් නොමැති වීම වැදගත් නොවන්නේ නම්, බොහෝ විට ඔබ dplyrහෝ data.tableවිසඳුම් භාවිතා කළ යුතුය base::order.


මම මෑතකදී CRAN පැකේජයකට sort.data.frame එකතු කළ අතර එය මෙහි සාකච්ඡා කර ඇති පරිදි පන්ති අනුකූල වේ: sort.data.frame සඳහා සාමාන්‍ය / ක්‍රම අනුකූලතාවයක් ඇති කිරීමට හොඳම ක්‍රමය?

එබැවින්, data.frame dd අනුව, ඔබට පහත පරිදි වර්ග කළ හැකිය:

dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"), 
      levels = c("Low", "Med", "Hi"), ordered = TRUE),
      x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
      z = c(1, 1, 1, 2))
library(taRifx)
sort(dd, f= ~ -z + b )

ඔබ මෙම ශ්‍රිතයේ මුල් කතුවරුන්ගෙන් කෙනෙක් නම් කරුණාකර මාව සම්බන්ධ කරගන්න. පොදු වසම පිළිබඳ සාකච්ඡාව මෙහි ඇත: http://chat.stackoverflow.com/transcript/message/1094290#1094290


ඉහත ත්‍රෙඩ් එකේ හැඩ්ලි පෙන්වා දුන් පරිදි ඔබට arrange()ශ්‍රිතය භාවිතා කළ හැකිය plyr:

library(plyr)
arrange(dd,desc(z),b)

මිණුම් සලකුණු: ගැටුම් රාශියක් ඇති බැවින් මම සෑම පැකේජයක්ම නව R සැසියකට පටවා ඇති බව සලකන්න. විශේෂයෙන් doBy පැකේජය පැටවීමේදී sort"පහත දැක්වෙන වස්තුව (ය) 'x (ස්ථානය 17)' වලින් ආවරණය කර ඇත: b, x, y, z", සහ Deducer පැකේජය පැටවීම sort.data.frameකෙවින් රයිට් හෝ taRifx පැකේජයෙන් නැවත ලියයි.

#Load each time
dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"), 
      levels = c("Low", "Med", "Hi"), ordered = TRUE),
      x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
      z = c(1, 1, 1, 2))
library(microbenchmark)

# Reload R between benchmarks
microbenchmark(dd[with(dd, order(-z, b)), ] ,
    dd[order(-dd$z, dd$b),],
    times=1000
)

මධ්‍ය කාලය:

dd[with(dd, order(-z, b)), ] 778 කි

dd[order(-dd$z, dd$b),] 788 කි

library(taRifx)
microbenchmark(sort(dd, f= ~-z+b ),times=1000)

මධ්‍ය කාලය: 1,567

library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=1000)

මධ්‍ය කාලය: 862

library(doBy)
microbenchmark(orderBy(~-z+b, data=dd),times=1000)

මධ්‍ය කාලය: 1,694

පැකේජය පැටවීමට doBy හොඳ කාලයක් ගතවන බව සලකන්න.

library(Deducer)
microbenchmark(sortData(dd,c("z","b"),increasing= c(FALSE,TRUE)),times=1000)

අඩු කරන්නා පැටවීමට නොහැකි විය. JGR කොන්සෝලය අවශ්‍යයි.

esort <- function(x, sortvar, ...) {
attach(x)
x <- x[with(x,order(sortvar,...)),]
return(x)
detach(x)
}

microbenchmark(esort(dd, -z, b),times=1000)

ඇමුණුම / වෙන්වීම හේතුවෙන් මයික්‍රොබෙන්ච්මාර්ක් සමඟ අනුකූල වන බවක් නොපෙනේ.


m <- microbenchmark(
  arrange(dd,desc(z),b),
  sort(dd, f= ~-z+b ),
  dd[with(dd, order(-z, b)), ] ,
  dd[order(-dd$z, dd$b),],
  times=1000
  )

uq <- function(x) { fivenum(x)[4]}  
lq <- function(x) { fivenum(x)[2]}

y_min <- 0 # min(by(m$time,m$expr,lq))
y_max <- max(by(m$time,m$expr,uq)) * 1.05

p <- ggplot(m,aes(x=expr,y=time)) + coord_cartesian(ylim = c( y_min , y_max )) 
p + stat_summary(fun.y=median,fun.ymin = lq, fun.ymax = uq, aes(fill=expr))

මයික්‍රොබෙන්ච්මාර්ක් කුමන්ත්‍රණය

(රේඛා පහළ කාර්තුවේ සිට ඉහළ කාර්තුව දක්වා විහිදේ, තිත යනු මධ්‍යන්‍යයයි)


මෙම ප්රතිඵල ලබා සහ සරල එදිරිව වේගය බර, මම කිරීම සඳහා අනුමැතිය ලබා දීමට ඇති කියලා arrangeතුළ plyrපැකේජය . එය සරල වාක්‍ය ඛණ්ඩයක් ඇති අතර මූලික R විධානයන් මෙන් ඒවායේ කැටි ගැසුණු යන්ත්‍ර සමඟ වේගවත් වේ. සාමාන්‍යයෙන් දීප්තිමත් හැඩ්ලි වික්හැම් වැඩ. එය සමඟ මට ඇති එකම ශෝකය නම්, එය වර්ගීකරණ වස්තූන් කැඳවන සම්මත R නාමකරණය බිඳ දැමීමයි sort(object), නමුත් ඉහත සම්බන්ධිත ප්‍රශ්නයේ සාකච්ඡා කර ඇති ගැටළු හේතුවෙන් හැඩ්ලි එසේ කළේ මන්දැයි මට වැටහේ.


3
ඉහත ggplot2 මයික්‍රොබෙන්ච්මාර්ක් ශ්‍රිතය දැන් ලබා ගත හැකිය taRifx::autoplot.microbenchmark.
අරි බී. ෆ්‍රීඩ්මන්

Ri ඇරිබී ෆ්‍රීඩ්මන් y අක්ෂයේ අන්තරයන් මොනවාද / පරිමාණය කුමක්ද?
naught101

ax naught101 y අක්ෂය 0 න් ආරම්භ වේ. පරිමාණය මයික්‍රෝ තත්පර විය යුතුය.
අරි බී. ෆ්‍රීඩ්මන්

2
@AME නියැදියෙහි වර්ග කර ඇති ආකාරය දෙස බලන්න b. පෙරනිමිය නඟින්නෙන් වර්ග කර ඇත, එබැවින් ඔබ එය ඔතා නොගන්න desc. දෙකෙහිම නැගීම : arrange(dd,z,b). දෙකේම බැස: arrange(dd,desc(z),desc(b)).
අරි බී. ෆ්‍රීඩ්මන්

2
අනුව ?arrange: "# සටහන: ප්ලයිර් ශ්‍රිත මඟින් row.names ආරක්ෂා නොකරයි". arrange()කෙනෙකුට තබා ගැනීමට අවශ්‍ය නම් මෙය විශිෂ්ට ශ්‍රිතයක් උපපෝෂිත කරයි row.names.
ලන්ඩ්‍රෝනි

151

ඩර්ක්ගේ පිළිතුර විශිෂ්ටයි. data.frameS සහ data.tables සුචිගත කිරීම සඳහා භාවිතා කරන වාක්‍ය ඛණ්ඩයේ ප්‍රධාන වෙනසක් ද එය ඉස්මතු කරයි :

## The data.frame way
dd[with(dd, order(-z, b)), ]

## The data.table way: (7 fewer characters, but that's not the important bit)
dd[order(-z, b)]

ඇමතුම් දෙක අතර වෙනස කුඩා නමුත් එය වැදගත් ප්‍රතිවිපාක ගෙන දිය හැකිය. විශේෂයෙන් ඔබ නිෂ්පාදන කේතය ලියන්නේ නම් සහ / හෝ ඔබේ පර්යේෂණයේ නිරවද්‍යතාව ගැන සැලකිලිමත් වන්නේ නම්, විචල්‍ය නම් අනවශ්‍ය ලෙස පුනරාවර්තනය වීම වළක්වා ගැනීම වඩාත් සුදුසුය. data.table මෙය කිරීමට ඔබට උදව් කරයි.

විචල්ය නාම පුනරාවර්තනය කිරීමෙන් ඔබ කරදරයට පත් වන්නේ කෙසේද යන්න පිළිබඳ උදාහරණයක් මෙන්න:

ඩර්ක්ගේ පිළිතුරෙන් සන්දර්භය වෙනස් කරමු, මෙය විශාල වස්තු නාමයක් ඇති විශාල ව්‍යාපෘතියක කොටසක් බවත් ඒවා දිගු හා අර්ථවත් බවත් කියමු; ඒ වෙනුවට ddඑය හැඳින්වේ quarterlyreport. එය බවට පත්වන්නේ:

quarterlyreport[with(quarterlyreport,order(-z,b)),]

හරි හොදයි. එහි කිසිදු වරදක් නැත. ඊළඟට ඔබේ ලොක්කා ඔබෙන් ඉල්ලා සිටින්නේ අවසාන කාර්තුවේ වාර්තාව වාර්තාවට ඇතුළත් කරන ලෙසයි. ඔබ ඔබේ කේතය හරහා ගොස් lastquarterlyreportවිවිධ ස්ථානවල වස්තුවක් එකතු කර කෙසේ හෝ (පෘථිවියේ කෙසේද?) ඔබ මෙය අවසන් කරන්නේ:

quarterlyreport[with(lastquarterlyreport,order(-z,b)),]

ඔබ අදහස් කළේ එය නොවේ, නමුත් ඔබ එය වේගයෙන් සිදු කළ නිසාත් එය සමාන කේතයක පිටුවක පිහිටා ඇති නිසාත් ඔබ එය හඳුනා නොගත්තේය. කේතය වැටෙන්නේ නැත (අනතුරු ඇඟවීමක් සහ දෝෂයක් නොමැත) මන්ද එය ඔබ අදහස් කළේ යැයි R සිතන බැවිනි. ඔබගේ වාර්තාව කියවන කවුරුන් හෝ එය සොයා ගනී යැයි ඔබ බලාපොරොත්තු වනු ඇත, නමුත් සමහර විට ඔවුන් එසේ නොකරනු ඇත. ඔබ ක්‍රමලේඛන භාෂාවන් සමඟ වැඩ කරන්නේ නම් මෙම තත්වය සියල්ලම හුරුපුරුදු විය හැකිය. එය ඔබ පවසන "යතුරු ලියනයකි". මම ඔයාගේ ලොක්කාට කියන "යතුරු ලියනය" හදන්නම්.

දී data.tableඅපි මේ වගේ කුඩා තොරතුරු ගැන සැලකිලිමත් වෙනවා. එබැවින් විචල්‍ය නම් දෙවරක් ටයිප් කිරීමෙන් වළක්වා ගැනීම සඳහා අපි සරල දෙයක් කර ඇත්තෙමු. ඉතා සරල දෙයක්. දැනටමත් ස්වයංක්‍රීයව iරාමුව තුළ ඇගයීමට ලක් කෙරේ dd. ඔබට කිසිසේත් අවශ්‍ය නොවේ with().

වෙනුවට

dd[with(dd, order(-z, b)), ]

එය සාධාරණයි

dd[order(-z, b)]

ඒ වෙනුවට

quarterlyreport[with(lastquarterlyreport,order(-z,b)),]

එය සාධාරණයි

quarterlyreport[order(-z,b)]

එය ඉතා කුඩා වෙනසක්, නමුත් එය එක් දිනක් ඔබේ බෙල්ල බේරා ගත හැකිය. මෙම ප්‍රශ්නයට වෙනස් පිළිතුරු කිරා මැන බැලීමේදී, විචල්ය නාමවල පුනරාවර්තන තීරණය කිරීමේ ඔබේ නිර්ණායකයක් ලෙස සලකා බලන්න. සමහර පිළිතුරු වලට පුනරාවර්තන කිහිපයක් ඇත, අනෙක් ඒවාට කිසිවක් නැත.


9
+1 මෙය ඉතා වැදගත් කරුණක් වන අතර බොහෝ විට මා කෝපයට පත් කළ R හි වාක්‍ය ඛණ්ඩය පිළිබඳ විස්තරයක් ලබා ගනී. subset()එකම ඇමතුමක් තුළ එකම වස්තුව නැවත නැවත යොමු නොකිරීමට මම සමහර විට භාවිතා කරමි .
ජොෂ් ඕ බ්‍රයන්

2
. naught101 data.table FAQ 1.9 එයට පිළිතුරු දෙයිද?
මැට් ඩව්ල්

6
මම හිතන්නේ ඔබට setorderමෙහි නව ශ්‍රිතයක් එකතු කළ හැකිය, මන්ද මෙම නූල් අප සියලු orderවර්ගවල ඩියුප් යවන ස්ථානයයි .
ඩේවිඩ් අරන්බර්ග්

127

මෙහි විශිෂ්ට පිළිතුරු රාශියක් ඇත, නමුත් මට ඉක්මනින් හා පහසුවෙන් මතක තබා ගත හැකි එකම වාක්‍ය ඛණ්ඩය dplyr ලබා දෙයි (එබැවින් දැන් බොහෝ විට භාවිතා කරන්න):

library(dplyr)
# sort mtcars by mpg, ascending... use desc(mpg) for descending
arrange(mtcars, mpg)
# sort mtcars first by mpg, then by cyl, then by wt)
arrange(mtcars , mpg, cyl, wt)

OP හි ගැටලුව සඳහා:

arrange(dd, desc(z),  b)

    b x y z
1 Low C 9 2
2 Med D 3 1
3  Hi A 8 1
4  Hi A 9 1

2
මගේ තීරු හෝ වර්ගය සාධකය (හෝ ඒ හා සමාන දෙයක්) වූ විට පිළිගත් පිළිතුර ක්‍රියා නොකරනු ඇති අතර මෙම සාධක තීරුව සඳහා බැසීමේ විලාසිතාව අනුව වර්ග කිරීමට මට අවශ්‍යය. නමුත් මෙය හොඳින් ක්‍රියාත්මක වේ! ඔබට ස්තුතියි!
සහීල් ගොඩ්හාන්

10
"පමණක්" ඇයි? Data.table dd[order(-z, b)]භාවිතා කිරීමට හා මතක තබා ගැනීමට පහසු බව මට පෙනේ .
මැට් ඩව්ල්

2
එකඟ විය, එම ක්‍රම දෙක අතර වැඩි යමක් නොමැති අතර තවත් බොහෝ ආකාරවලින් data.tableඑය විශාල දායකත්වයක් සපයයි R. මම හිතන්නේ, සමහර විට අඩු වරහන් කට්ටලයක් (හෝ අඩු වරහන් වර්ගයක්) තිබීම, සංජානන භාරය යන්තම් වටහා ගත හැකි ප්‍රමාණයකින් අඩු කරයි.
බෙන්

7
මට නම් එය arrange()සම්පූර්ණයෙන්ම ප්‍රකාශිත, dd[order(-z, b)]එසේ නොවේ.
මුල්ලෙෆා

84

ආර් පැකේජය data.tableදෙකම සපයයි වේගයෙන් හා මතකය කාර්යක්ෂම කිරීම සඳහා ඇනවුම් data.tables සරල කාරක රීති (මතෙ ඉතා අලංකාර ලෙස ඉස්මතු වී ඇති කොටසක් සමග ඔහුගේ පිළිතුරු ). එතැන් සිට සෑහෙන වැඩිදියුණු කිරීම් සහ නව කාර්යයක් සිදු setorder()වී ඇත. සිට v1.9.5+, data.framessetorder() සමඟ ද ක්‍රියා කරයි .

පළමුවෙන්ම, අපි ප්‍රමාණවත් තරම් දත්ත කට්ටලයක් නිර්මාණය කර වෙනත් පිළිතුරු වලින් සඳහන් විවිධ ක්‍රම මිණුම් සලකුණු කර ඉන්පසු දත්ත.ටේබල් හි විශේෂාංග ලැයිස්තුගත කරමු .

දත්ත:

require(plyr)
require(doBy)
require(data.table)
require(dplyr)
require(taRifx)

set.seed(45L)
dat = data.frame(b = as.factor(sample(c("Hi", "Med", "Low"), 1e8, TRUE)),
                 x = sample(c("A", "D", "C"), 1e8, TRUE),
                 y = sample(100, 1e8, TRUE),
                 z = sample(5, 1e8, TRUE), 
                 stringsAsFactors = FALSE)

මිණුම් සලකුණු:

වාර්තා කර ඇති වේලාවන් system.time(...)පහත පෙන්වා ඇති මෙම කාර්යයන් මත ක්‍රියාත්මක වේ. වේලාවන් පහත දැක්වේ (මන්දගාමී සිට වේගවත්ම අනුපිළිවෙලට).

orderBy( ~ -z + b, data = dat)     ## doBy
plyr::arrange(dat, desc(z), b)     ## plyr
arrange(dat, desc(z), b)           ## dplyr
sort(dat, f = ~ -z + b)            ## taRifx
dat[with(dat, order(-z, b)), ]     ## base R

# convert to data.table, by reference
setDT(dat)

dat[order(-z, b)]                  ## data.table, base R like syntax
setorder(dat, -z, b)               ## data.table, using setorder()
                                   ## setorder() now also works with data.frames 

# R-session memory usage (BEFORE) = ~2GB (size of 'dat')
# ------------------------------------------------------------
# Package      function    Time (s)  Peak memory   Memory used
# ------------------------------------------------------------
# doBy          orderBy      409.7        6.7 GB        4.7 GB
# taRifx           sort      400.8        6.7 GB        4.7 GB
# plyr          arrange      318.8        5.6 GB        3.6 GB 
# base R          order      299.0        5.6 GB        3.6 GB
# dplyr         arrange       62.7        4.2 GB        2.2 GB
# ------------------------------------------------------------
# data.table      order        6.2        4.2 GB        2.2 GB
# data.table   setorder        4.5        2.4 GB        0.4 GB
# ------------------------------------------------------------
  • data.tableගේ DT[order(...)]රීති බොහෝදුරට ~ 10x වේගවත් වෙනත් ක්රම (වේගවත්ම වඩා dplyrලෙස මතකය සමාන පානය අතර,) dplyr.

  • data.tableගේ setorder()විය ~ 14x වේගවත් වෙනත් ක්රම වේගවත්ම (වඩා dplyr, ගෙන ඇති අතර) පමණක් 0.4GB අමතර මතකයක් . datදැන් අපට අවශ්‍ය අනුපිළිවෙලට ඇත (එය යොමු අනුව යාවත්කාලීන වන පරිදි).

data.table විශේෂාංග:

වේගය:

  • data.table හි ඇණවුම අතිශයින් වේගවත් වන්නේ එය රේඩික්ස් අනුපිළිවෙල ක්‍රියාත්මක කරන බැවිනි .

  • Data.table හි වේගවත් ඇණවුම DT[order(...)]භාවිතා කිරීම සඳහා සින්ටැක්ස් අභ්‍යන්තරව ප්‍රශස්තිකරණය කර ඇත. ඔබට හුරුපුරුදු පාදක R සින්ටැක්ස් භාවිතා කළ හැකි නමුත් ක්‍රියාවලිය වේගවත් කරන්න (සහ අඩු මතකයක් භාවිතා කරන්න).

මතකය:

  • බොහෝ විට, නැවත සකස් කිරීමෙන් පසු අපට මුල් data.frame හෝ data.table අවශ්‍ය නොවේ . එනම්, අපි සාමාන්‍යයෙන් ප්‍රති result ලය එකම වස්තුවකට නැවත පවරමු, උදාහරණයක් ලෙස:

    DF <- DF[order(...)]

    ගැටළුව වන්නේ මේ සඳහා අවම වශයෙන් දෙවරක් (2x) මුල් වස්තුවේ මතකය අවශ්‍ය වීමයි. විය මතක කාර්යක්ෂම , data.table නිසා ද උත්සවයකට සපයයි setorder().

    setorder()කිසිදු අමතර පිටපත් නොකර data.tables by reference ( ස්ථානයේ ) නැවත සකසයි . එය භාවිතා කරන්නේ එක් තීරුවක ප්‍රමාණයට සමාන අමතර මතකයක් පමණි.

වෙනත් විශේෂාංග:

  1. එය මනින්නේ integer, logical, numeric, characterහා පවා bit64::integer64වර්ග.

    බව සටහන factor, Date, POSIXctආදිය .. පන්ති සියලු ඇත integer/ numericවර්ග අමතර ලක්ෂණ සහිත යට සහ ඒ නිසා මෙන්ම සහාය දක්වයි.

  2. R පාදමෙහි, -අනුපිළිවෙල අඩු කිරීමෙන් අනුපිළිවෙලින් වර්ග කිරීම සඳහා අපට අක්ෂර දෛශිකයක් භාවිතා කළ නොහැක . ඒ වෙනුවට අප භාවිතා කළ -xtfrm(.)යුතුය.

    කෙසේ වෙතත්, data.table හි , අපට කළ හැක්කේ, උදාහරණයක් ලෙස, dat[order(-x)]හෝ setorder(dat, -x).


Data.table පිළිබඳ මෙම උපදේශාත්මක පිළිතුරට ස්තූතියි. "උපරිම මතකය" යනු කුමක්ද සහ ඔබ එය ගණනය කළේ කෙසේද යන්න මට තේරෙන්නේ නැත. කරුණාකර ඔබට පැහැදිලි කළ හැකිද? ඔබට ස්තුතියි !
ජූලියන් නවරේ

මම උපකරණ -> ප්‍රතිපාදන භාවිතා කළ අතර “සියලු ගොඩවල් සහ වෙන් කිරීම් VM” ප්‍රමාණය වාර්තා කළෙමි .
අරුන්

2
Comment ඔබේ අදහසෙහි ඇති උපකරණ සබැඳිය අක්‍රීය කරන්න. යාවත්කාලයක් පළ කිරීමට සැලකිලිමත්ද?
මයිකල් චිරිකෝ

: @MichaelChirico මෙන්න භාණ්ඩ ගැන තොරතුරු වෙත සබැඳියක් ඇපල් විසින් ගන්නා developer.apple.com/library/content/documentation/...
n1k31t4

74

ආර් විකියේ ඉඟි කොටසේ පළ කර ඇති කෙවින් රයිට්ගේ මෙම (ඉතා ප්‍රයෝජනවත්) ක්‍රියාකාරිත්වය සමඟ මෙය පහසුවෙන් සාක්ෂාත් කරගත හැකිය.

sort(dd,by = ~ -z + b)
#     b x y z
# 4 Low C 9 2
# 2 Med D 3 1
# 1  Hi A 8 1
# 3  Hi A 9 1

2
මෙම ශ්‍රිතයේ භාවිතා කරන ඇල්ගොරිතමයේ මිණුම් සලකුණු කිරීම සඳහා මගේ පිළිතුර බලන්න.
අරි බී. ෆ්‍රීඩ්මන්


40

ඔබ හිතන්න data.frame Aඔබ කැඳවා තීරුව භාවිතා කර නිරාකරණය කිරීමට අවශ්ය xඅවරෝහණ. වර්ග කළ අය අමතන්නdata.frame newdata

newdata <- A[order(-A$x),]

ඔබට නැගීමේ අනුපිළිවෙල අවශ්‍ය නම් "-"කිසිවක් වෙනුවට ආදේශ කරන්න. ඔබට එවැනි දෙයක් තිබිය හැකිය

newdata <- A[order(-A$x, A$y, -A$z),]

කොහේද xසහ zතීරු කිහිපයක් තිබේ data.frame A. මෙයින් අදහස් data.frame Aකරන්නේ xබැසයාම, yනැගීම සහ zබැසයාම අනුව වර්ග කිරීමයි.


33

SQL ස්වාභාවිකවම ඔබ වෙත පැමිණෙන්නේ නම්, කෝඩ් අදහස් කළ පරිදි sqldfපැකේජය හසුරුවයි ORDER BY.


7
එම්.ජේ.එම්, මෙම පැකේජය පෙන්වා දීමට ස්තූතියි. එය ඇදහිය නොහැකි තරම් නම්‍යශීලී වන අතර මගේ වැඩවලින් අඩක් දැනටමත් වර්ග දත්ත ගබඩාවලින් ඇදගෙන යාම නිසා R හි බොහෝ දේ ඉගෙන ගැනීමට වඩා පහසුය.
බ්‍රැන්ඩන් බර්ටෙල්සන්

32

විකල්පයක් ලෙස, Deducer පැකේජය භාවිතා කිරීම

library(Deducer)
dd<- sortData(dd,c("z","b"),increasing= c(FALSE,TRUE))

20

ක්‍රමලේඛනගතව වර්ග කරන්නේ කෙසේද යන්න සඳහා OP හි එකතු කරන ලද අදහසකට ප්‍රතිචාර වශයෙන්:

භාවිතා කිරීම dplyrසහdata.table

library(dplyr)
library(data.table)

dplyr

භාවිතා කරන්න arrange_, එය සඳහා සම්මත ඇගයීම් අනුවාදය වේ arrange.

df1 <- tbl_df(iris)
#using strings or formula
arrange_(df1, c('Petal.Length', 'Petal.Width'))
arrange_(df1, ~Petal.Length, ~Petal.Width)
    Source: local data frame [150 x 5]

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          (dbl)       (dbl)        (dbl)       (dbl)  (fctr)
1           4.6         3.6          1.0         0.2  setosa
2           4.3         3.0          1.1         0.1  setosa
3           5.8         4.0          1.2         0.2  setosa
4           5.0         3.2          1.2         0.2  setosa
5           4.7         3.2          1.3         0.2  setosa
6           5.4         3.9          1.3         0.4  setosa
7           5.5         3.5          1.3         0.2  setosa
8           4.4         3.0          1.3         0.2  setosa
9           5.0         3.5          1.3         0.3  setosa
10          4.5         2.3          1.3         0.3  setosa
..          ...         ...          ...         ...     ...


#Or using a variable
sortBy <- c('Petal.Length', 'Petal.Width')
arrange_(df1, .dots = sortBy)
    Source: local data frame [150 x 5]

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          (dbl)       (dbl)        (dbl)       (dbl)  (fctr)
1           4.6         3.6          1.0         0.2  setosa
2           4.3         3.0          1.1         0.1  setosa
3           5.8         4.0          1.2         0.2  setosa
4           5.0         3.2          1.2         0.2  setosa
5           4.7         3.2          1.3         0.2  setosa
6           5.5         3.5          1.3         0.2  setosa
7           4.4         3.0          1.3         0.2  setosa
8           4.4         3.2          1.3         0.2  setosa
9           5.0         3.5          1.3         0.3  setosa
10          4.5         2.3          1.3         0.3  setosa
..          ...         ...          ...         ...     ...

#Doing the same operation except sorting Petal.Length in descending order
sortByDesc <- c('desc(Petal.Length)', 'Petal.Width')
arrange_(df1, .dots = sortByDesc)

වැඩි විස්තර මෙතැනින්: https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html

ප්‍රකාශනයක් ඇගයීමට පරිසරය ග්‍රහණය කර ගන්නා බැවින් සූත්‍රය භාවිතා කිරීම වඩා හොඳය

data.table

dt1 <- data.table(iris) #not really required, as you can work directly on your data.frame
sortBy <- c('Petal.Length', 'Petal.Width')
sortType <- c(-1, 1)
setorderv(dt1, sortBy, sortType)
dt1
     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
  1:          7.7         2.6          6.9         2.3 virginica
  2:          7.7         2.8          6.7         2.0 virginica
  3:          7.7         3.8          6.7         2.2 virginica
  4:          7.6         3.0          6.6         2.1 virginica
  5:          7.9         3.8          6.4         2.0 virginica
 ---                                                            
146:          5.4         3.9          1.3         0.4    setosa
147:          5.8         4.0          1.2         0.2    setosa
148:          5.0         3.2          1.2         0.2    setosa
149:          4.3         3.0          1.1         0.1    setosa
150:          4.6         3.6          1.0         0.2    setosa

19

orderපහත දැක්වෙන උදාහරණය සමඟ මම ඉගෙන ගත් අතර පසුව එය දිගු කලක් තිස්සේ ව්‍යාකූල විය:

set.seed(1234)

ID        = 1:10
Age       = round(rnorm(10, 50, 1))
diag      = c("Depression", "Bipolar")
Diagnosis = sample(diag, 10, replace=TRUE)

data = data.frame(ID, Age, Diagnosis)

databyAge = data[order(Age),]
databyAge

නිසා මෙම උදාහරණය වැඩ එකම හේතුව orderවිසින් තෝරා බේරා ගැනීමේ ඇත vector Age, නැත නම් තීරුව විසින් Ageතුළ data frame data.

මෙය බැලීමට read.tableතරමක් වෙනස් තීරු නම් සහිතව සහ ඉහත කිසිදු දෛශිකයක් භාවිතා නොකර සමාන දත්ත රාමුවක් සාදන්න :

my.data <- read.table(text = '

  id age  diagnosis
   1  49 Depression
   2  50 Depression
   3  51 Depression
   4  48 Depression
   5  50 Depression
   6  51    Bipolar
   7  49    Bipolar
   8  49    Bipolar
   9  49    Bipolar
  10  49 Depression

', header = TRUE)

orderදෛශිකයක් නම් කර නොමැති නිසා ඉහත රේඛා ව්‍යුහය තවදුරටත් ක්‍රියාත්මක නොවේ age:

databyage = my.data[order(age),]

, පහත දැක්වෙන රේඛාව නිසා වැඩ orderඇති තීරුවෙහි මත ආකාරයේ ageදී my.data.

databyage = my.data[order(my.data$age),]

මෙතරම් කාලයක් තිස්සේ මෙම උදාහරණයෙන් මා කෙතරම් ව්‍යාකූල වී ඇත්ද යන්න පළ කිරීම වටී යැයි මම සිතුවෙමි. මෙම ලිපිය නූල් සඳහා සුදුසු යැයි නොසැලකේ නම් මට එය ඉවත් කළ හැකිය.

සංස්කරණය කරන්න: 2014 මැයි 13

තීරු නම් සඳහන් නොකර සෑම තීරුවකින්ම දත්ත රාමුවක් වර්ග කිරීමේ සාමාන්‍ය ක්‍රමයක් පහත දැක්වේ. පහත කේතය වමේ සිට දකුණට හෝ දකුණෙන් වමට වර්ග කරන්නේ කෙසේදැයි පෙන්වයි. සෑම තීරුවක්ම සංඛ්‍යාත්මක නම් මෙය ක්‍රියාත්මක වේ. අක්ෂර තීරුවක් එකතු කර මා උත්සාහ කර නැත.

මම do.callමාසයකට හෝ දෙකකට පෙර වෙනත් වෙබ් අඩවියක පැරණි පෝස්ට් එකකින් කේතය සොයා ගත්තෙමි , නමුත් පුළුල් හා දුෂ්කර සෙවීමකින් පසුව පමණි. මට දැන් එම තනතුර වෙනත් ස්ථානයකට ගෙන යා හැකි යැයි විශ්වාස නැත. වර්තමාන නූල් සඳහා ඇණවුම් කිරීම සඳහා පළමු පහර වේ data.frameදී R. ඉතින්, මම හිතුවා මගේ මුල් do.callකේතයේ පුළුල් කළ අනුවාදය ප්‍රයෝජනවත් වේවි කියා.

set.seed(1234)

v1  <- c(0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1)
v2  <- c(0,0,0,0, 1,1,1,1, 0,0,0,0, 1,1,1,1)
v3  <- c(0,0,1,1, 0,0,1,1, 0,0,1,1, 0,0,1,1)
v4  <- c(0,1,0,1, 0,1,0,1, 0,1,0,1, 0,1,0,1)

df.1 <- data.frame(v1, v2, v3, v4) 
df.1

rdf.1 <- df.1[sample(nrow(df.1), nrow(df.1), replace = FALSE),]
rdf.1

order.rdf.1 <- rdf.1[do.call(order, as.list(rdf.1)),]
order.rdf.1

order.rdf.2 <- rdf.1[do.call(order, rev(as.list(rdf.1))),]
order.rdf.2

rdf.3 <- data.frame(rdf.1$v2, rdf.1$v4, rdf.1$v3, rdf.1$v1) 
rdf.3

order.rdf.3 <- rdf.1[do.call(order, as.list(rdf.3)),]
order.rdf.3

4
ඩේටා ෆ්‍රේම් වෙනුවට ඔබේ දත්ත ඩේටා ටේබල් එකක ගබඩා කළහොත් එම සින්ටැක්ස් ක්‍රියාත්මක වේ: require(data.table); my.dt <- data.table(my.data); my.dt[order(age)]මෙය ක්‍රියාත්මක වන්නේ තීරු නම් වරහන් තුළ ලබා දී ඇති බැවිනි.
ෆ්‍රෑන්ක්

මම හිතන්නේ නැහැ මේ downvote මෙතන අවශ්ය වන අතර, නමුත් මම මේ බොහෝ එකතු හිතන්නේ වත් ප්රශ්නය , විශේෂයෙන් පිළිතුරු පවතින කට්ටලයක් සලකා පැත්තේ, ඇති අතර, සමහරක් දැනටමත් සමග අවශ්යතාව අල්ලා data.frameහෝ භාවිතා කිරීම ගේ withහෝ $.
A5C1D2H2I1M1N2O1R2T1

1
මේ සඳහා upvote do.callමඟින් බහු තීරු දත්ත රාමුවක් වර්ග කිරීම කෙටි වැඩ කරයි. සරලව do.call(sort, mydf.obj)හා ලස්සන කඳුරැල්ල වර්ග කිරීමක් සිදුවනු ඇත.
ඇඩම්ඕ

18

ඩර්ක්ගේ පිළිතුර හොඳයි, නමුත් ඔබට දිගටම පැවතීමට අවශ්‍ය නම්, එම දත්ත රාමුවේ නමට නැවත වර්ග කිරීම අවශ්‍ය වේ. උදාහරණ කේතය භාවිතා කිරීම:

dd <- dd[with(dd, order(-z, b)), ] 

13

Dplyer හි () සැකසීම මගේ ප්‍රියතම විකල්පයයි. පයිප්ප ක්‍රියාකරු භාවිතා කර අවම වශයෙන් වැදගත් සිට වඩාත්ම වැදගත් අංශයට යන්න

dd1 <- dd %>%
    arrange(z) %>%
    arrange(desc(x))

8

තීරු අංක අනුව වර්ග කිරීම ගැන වැඩි යමක් පවසා නැති හෙයින්, සම්පූර්ණත්වය උදෙසා ... එය බොහෝ විට සුදුසු නොවන බව නිසැකවම තර්ක කළ හැකිය (මන්ද තීරු වල අනුපිළිවෙල වෙනස් විය හැකි අතර, දෝෂ වලට මග පෑදේ), නමුත් සමහර විශේෂිත අවස්ථාවන්හිදී (නිදසුනක් ලෙස ඔබට ඉක්මන් වැඩක් කිරීමට අවශ්‍ය වූ විට සහ තීරු ඇණවුම් වෙනස් කිරීමේ අවදානමක් නොමැති විට), එය කළ යුතු වඩාත්ම බුද්ධිමත් දෙය විය හැකිය, විශේෂයෙන් තීරු විශාල සංඛ්‍යාවක් සමඟ කටයුතු කිරීමේදී.

එවැනි අවස්ථාවක, do.call()ගලවා ගැනීමට පැමිණේ:

ind <- do.call(what = "order", args = iris[,c(5,1,2,3)])
iris[ind, ]

##        Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
##    14           4.3         3.0          1.1         0.1     setosa
##    9            4.4         2.9          1.4         0.2     setosa
##    39           4.4         3.0          1.3         0.2     setosa
##    43           4.4         3.2          1.3         0.2     setosa
##    42           4.5         2.3          1.3         0.3     setosa
##    4            4.6         3.1          1.5         0.2     setosa
##    48           4.6         3.2          1.4         0.2     setosa
##    7            4.6         3.4          1.4         0.3     setosa
##    (...)

6

බොහෝ කලකට පෙර යාන්ත්‍රික කාඩ්පත් වර්ග කරන්නන් මෙන්, පළමුව අවම වැදගත් යතුරකින් වර්ග කරන්න, ඉන්පසු ඊළඟට වඩාත්ම වැදගත් යනාදිය. පුස්තකාලයක් අවශ්‍ය නොවේ, යතුරු ගණනක් සමඟ වැඩ කරයි.

 dd <- dd[order(dd$b, decreasing = FALSE),]

දැන් අපි වඩාත් වැදගත් යතුර කිරීමට සූදානම්. වර්ග කිරීම ස්ථායී වන අතර වඩාත්ම වැදගත් යතුරේ ඇති ඕනෑම බැඳීමක් දැනටමත් විසඳා ඇත.

dd <- dd[order(dd$z, decreasing = TRUE),]

මෙය වේගවත්ම නොවේ, නමුත් එය නිසැකවම සරල හා විශ්වාසදායක ය


6

සම්පූර්ණත්වය වෙනුවෙන්: ඔබ ද භාවිතා කළ හැකිය sortByCol()සිට උත්සවය BBmiscපැකේජය:

library(BBmisc)
sortByCol(dd, c("z", "b"), asc = c(FALSE, TRUE))
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1

කාර්ය සාධනය සංසන්දනය:

library(microbenchmark)
microbenchmark(sortByCol(dd, c("z", "b"), asc = c(FALSE, TRUE)), times = 100000)
median 202.878

library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=100000)
median 148.758

microbenchmark(dd[with(dd, order(-z, b)), ], times = 100000)
median 115.872

4
ඔබේ ක්‍රමය මන්දගාමී වන විට කාර්ය සාධන සංසන්දනයක් එක් කිරීම අමුතුයි ... කෙසේ වෙතත් පේළි 4 ක මිණුම් ලකුණක් භාවිතා කිරීමේ වටිනාකම සැක සහිතයිdata.frame
මයිකල් චිරිකෝ


4

තීරු n සඳහා මගේ ඇණවුම් ක්‍රියාවලිය ස්වයංක්‍රීය කිරීමට අවශ්‍ය වූ විට මම ඉහත විසඳුම් සමඟ පොරබදමින් සිටියෙමි, ඒවායේ තීරු නම් සෑම අවස්ථාවකම වෙනස් විය හැකිය. psychමෙය සරල ආකාරයකින් කිරීමට පැකේජයෙන් සුපිරි ප්‍රයෝජනවත් කාර්යයක් මට හමු විය :

dfOrder(myDf, columnIndices)

එහිදී columnIndicesඔබ ඔවුන් නිරාකරණය කිරීමට අවශ්ය කරන පිණිස, තීරු එකක් හෝ ඊට වැඩි දර්ශක වේ. වැඩි විස්තර මෙතැනින්:

'මනෝ' පැකේජයෙන් dfOrder ක්‍රියාකාරිත්වය

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.