programing

여러 열을 기준으로 데이터 프레임 행 정렬(순서 정렬)

linuxpc 2023. 6. 10. 08:30
반응형

여러 열을 기준으로 데이터 프레임 행 정렬(순서 정렬)

데이터 프레임을 여러 열로 정렬합니다.예를 들어 아래의 데이터 프레임을 사용하여 열 '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

추가 도구에 의존하지 않고 기능을 직접 사용할 수 있습니다. 바로 위에서 트릭을 사용하는 이 간단한 답변을 보십시오.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> 

(및 이그는것보다사하용고을름리열의그▁()▁rather다▁the보)을 사용하는 with()보다 쉽게/더 직접적으로 액세스할 수 있습니다.

선택 사항

  • orderbase
  • arrangedplyr
  • setorder그리고.setordervdata.table
  • arrangeplyr
  • sorttaRifx
  • orderBydoBy
  • sortDataDeducer

에는 대분의사합니다야용을 .dplyr또는data.table이 없는은 중요하지 . 이 에는 성이없것한않는, 솔션사용, 이경우의를 사용합니다.base::order.


나는 최근에 cran 패키지에 sort.data.frame을 추가하여 여기서 논의한 것처럼 클래스 호환성을 만들었습니다. sort.data.frame에 대한 일반/메소드 일관성을 만드는 가장 좋은 방법은 무엇입니까?

따라서 data.framed가 주어지면 다음과 같이 정렬할 수 있습니다.

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 )

만약 당신이 이 기능의 원작자 중 한 명이라면 저에게 연락해 주십시오.공공 도메인에 대한 논의는 다음과 같습니다. https://chat.stackoverflow.com/transcript/message/1094290#1094290


은 또한 있다니습수도를 할 수 .arrange()에서 합니다.plyr위의 스레드에서 Hadley가 지적했듯이:

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

벤치마크: 충돌이 많아서 새 R 세션에 각 패키지를 로드했습니다.하면 doBy 패키지가 로드됩니다.sort는 ' 17: x, y, z". ""는 " 위음개치 'x(에체가 17)' '됨마킹다: b, x, y, z" 및로 "Deducer 패키 덮기드쓰 어지서스로▁""를 .sort.data.frameKevin Wright는 Rifx입니다.

#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))

마이크로벤치마크 그림

(선은 하위 사분위수에서 상위 사분위수로 확장되며, 점은 중위수입니다.)


이러한 결과와 단순성 대 속도의 무게를 고려할 때, 저는 패키지에서 승인을 해야 할 것입니다.이것은 간단한 구문을 가지고 있지만 복잡한 처리를 통해 기본 R 명령만큼 빠릅니다.전형적으로 뛰어난 해들리 위컴의 작품입니다.그것에 대한 유일한 불만은 정렬 객체가 호출되는 표준 R 명명법을 위반한다는 것입니다.sort(object)하지만 위에 링크된 질문에서 논의된 문제로 인해 해들리가 왜 그런 식으로 했는지 이해합니다.

더크의 대답은 훌륭합니다. 인덱싱에 합니다.data.frame모래땅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이 작업을 도와줍니다.

다음은 변수 이름을 반복하면 문제가 발생할 수 있는 예입니다.

을 바꿔서, 있는 더 큰 의대답서바고꾸 에 것이많객이있은그길체있의름고이더대큰에신하일이자고라프더것들부이크의는미고가트젝로에락을맥▁where▁of▁let▁instead▁names▁this▁there에신대▁is▁part▁project▁ofs,▁from▁answer▁and▁dir▁and▁context▁the▁a▁bigger▁say'k'하더▁meaningful;,자s이크것▁change▁and고라일,▁long▁they▁are이부은고있많의체미의큰더프dd고라합니다라고 .quarterlyreport다음과 같습니다.

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

그래, 좋아. 아무 그것은 아무런 문제가 없어.다음에 당신의 상사는 지난 분기의 보고서를 보고서에 포함시키라고 요청합니다.코드를 하고, 를 추가합니다.lastquarterlyreport 어떻게든은 결국 :다한장도그어떻든게리고어게떻소서에체대양)? 당신은 결국 다음과 같이 됩니다.

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

그것은 당신이 의미한 것이 아니지만 당신은 그것을 빨리 했고 그것이 유사한 코드의 페이지에 자리잡고 있기 때문에 그것을 발견하지 못했습니다.R은 그것이 당신이 의미한 것이라고 생각하기 때문에 코드가 넘어가지 않습니다(경고 및 오류 없음).당신의 보고서를 읽는 사람은 누구든 그것을 발견하기를 바라겠지만, 그들은 그렇지 않을 수도 있습니다.프로그래밍 언어를 많이 사용하면 이 상황이 모두 익숙해질 수 있습니다.그것은 당신이 말할 "타이포"였습니다.당신이 당신의 상사에게 말할 "타이포"를 고치겠습니다.

우리는 이와 같은 작은 세부사항들에 대해 우려하고 있습니다.따라서 변수 이름을 두 번 입력하지 않도록 간단한 작업을 수행했습니다.아주 간단한 것. i는 의범내에평다의 틀 됩니다.dd이미, 자동으로.필없습다가 필요 없습니다.with()조금도.

대신에

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

이건 그저.

dd[order(-z, b)]

그리고 대신에

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

이건 그저.

quarterlyreport[order(-z,b)]

아주 작은 차이지만 언젠가는 당신의 목을 살릴 수 있을지도 모릅니다.이 질문에 대한 다양한 답변을 평가할 때 변수 이름의 반복 횟수를 계산하는 것을 고려하십시오.반복 횟수가 많은 답변도 있고 반복 횟수가 없는 답변도 있습니다.

여기에는 훌륭한 답변들이 많이 있지만, 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

패키지 R은 다음과 같습니다.data.tabledata.tables빠르고 메모리 효율적정렬을 모두 제공합니다(Matt가 답변에서 상당히 잘 강조한 부분).상당히 많은 개선이 있었고 또한 새로운 기능이 있었습니다.setorder()그 이후로부터v1.9.5+,setorder()또한 data.frames에서도 작동합니다.

먼저, 충분히 큰 데이터 세트를 생성하고 다른 답변에서 언급된 다양한 방법을 벤치마킹한 다음 data.table의 기능을 나열합니다.

데이터:

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.tableDT[order(...)]구문이 다른 방법보다 10배 더 빠름(dplyr )와도 동일한 양의 메모리를 소비합니다.dplyr.

  • data.tablesetorder()다른 방법보다 최대 14배 더 빠름(dplyr), 0.4만 취함GB 추가 메모리. dat이제 필요한 순서대로입니다(참고로 업데이트됨).

data.테이블 기능:

속도:

  • data.tableradix 순서를 구현하므로 순서가 매우 빠릅니다.

  • DT[order(...)]내부적으로 data.table을 사용하도록 최적화되어 있습니다.익숙한 기본 R 구문을 계속 사용할 수 있지만 프로세스 속도를 높일 수 있으며 메모리 사용량도 줄일 수 있습니다.

메모리:

  • 대부분은 재주문 후 원본 data.frame이나 data.table이 필요하지 않습니다.즉, 일반적으로 다음과 같은 결과를 동일한 개체에 다시 할당합니다.

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

    문제는 이 작업을 수행하려면 원래 개체의 메모리가 최소 두 배(2배) 이상 필요하다는 것입니다.따라서 메모리 효율성을 위해 data.table은 함수를 제공합니다.setorder().

    setorder()데이터 순서 변경. by reference(내부), 추가 복사본을 만들지 않습니다.한 열의 크기와 동일한 추가 메모리만 사용합니다.

기타 기능:

  1. 을 지원합니다.integer,logical,numeric,character ㅠㅠbit64::integer64types.

    :factor,Date,POSIXct ㅇㅇ.. 수업이 전부입니다.integer/numeric아래에 추가 특성이 있는 유형도 지원됩니다.

  2. 기본 R에서는 사용할 수 없습니다.-문자 벡터에서 해당 열을 내림차순으로 정렬합니다.는 대신우사합야니다해용는리합을 사용해야 .-xtfrm(.).

    그러나 data.table에서는 예를 들어 다음과 같이 할 수 있습니다.dat[order(-x)]또는setorder(dat, -x).

R 위키의 팁 섹션에 게시된 Kevin Wright의 이 (매우 유용한) 기능을 통해 쉽게 달성할 수 있습니다.

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

당신이 가지고 있다고 가정합니다.data.frame A은 다열을정합니렬고다려하여라는 .x내림차순정렬된 호출data.frame newdata

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

하려면 차순을경우대체는원하오름대▁then▁if체경을 대체합니다."-"무일푼으로당신은 다음과 같은 것을 가질 수 있습니다.

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

x그리고.z에 몇 .data.frame A이것은 정렬을 의미합니다.data.frame A타고x 강하,y과 오름차순z내림의

또는 패키지 doBy를 사용할 수 있습니다.

library(doBy)
dd <- orderBy(~-z+b, data=dd)

sqldf 핸들 패지핸ORDER BY커드의 의도대로

또는 패키지 디듀서 사용

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

dplyr의 arrange()는 제가 가장 좋아하는 옵션입니다.파이프 오퍼레이터를 사용하여 가장 중요하지 않은 측면에서 가장 중요한 측면으로 이동합니다.

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

프로그래밍 방식으로 정렬하는 방법에 대해 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.테이블

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

는 에대해배다니웠습다에 배웠습니다.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에 정렬합니다.agemy.data.

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

오랫동안 이 예를 보고 얼마나 혼란스러웠는지 볼 때, 저는 이것이 게시할 가치가 있다고 생각했습니다.이 게시물이 스레드에 적합하지 않다고 판단되면 제거할 수 있습니다.

편집: 2014년 5월 13일

다음은 열 이름을 지정하지 않고 모든 열을 기준으로 데이터 프레임을 정렬하는 일반화된 방법입니다.아래 코드는 왼쪽에서 오른쪽으로 또는 오른쪽에서 왼쪽으로 정렬하는 방법을 보여줍니다.이것은 모든 열이 숫자인 경우에 작동합니다.문자 열을 추가하여 시도하지 않았습니다.

나는 찾았습니다.do.call한 두 달 전에 다른 사이트의 오래된 게시물에 코드를 넣었지만, 광범위하고 어려운 검색 후에만 코드를 입력했습니다.저는 제가 지금 그 자리를 옮길 수 있을지 확신할 수 없습니다.현재 스레드는 주문을 위한 첫 번째 히트입니다.data.frameR그래서, 저는 그 원본의 확장된 버전이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

Dirk의 답변은 좋지만 지속적인 정렬이 필요하다면 해당 데이터 프레임의 이름에 다시 정렬을 적용하기를 원할 것입니다.예제 코드 사용:

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

완전성을 위해 열 번호별로 정렬하는 것에 대해 많이 언급되지 않았기 때문에...(열의 순서가 변경되어 오류로 가는 길이 열릴 수 있기 때문에) 종종 바람직하지 않다고 주장할 수 있지만, 일부 특정 상황(예를 들어, 빠른 작업이 필요하고 열이 순서를 변경할 위험이 없는 경우)에서는 가장 현명한 방법일 수 있습니다.특히 많은 수의 열을 다룰 때.

그런경는에우,는에,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
##    (...)

: 완성을위: 또사수있다니습할용해한을 할 수 .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

오래 전의 기계식 카드 정렬기처럼, 처음에는 최하위 키로 정렬하고, 다음에는 최상위 키로 정렬합니다.라이브러리가 필요하지 않으며, 임의의 수의 키와 오름차순 및 내림차순 키 조합으로 작동합니다.

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

이제 우리는 가장 중요한 열쇠를 할 준비가 되었습니다.정렬은 안정적이며 가장 중요한 키의 연결은 이미 해결되었습니다.

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

이것이 가장 빠르지는 않을 수 있지만, 확실히 간단하고 신뢰할 수 있습니다.

다른 다대안로으사, 다을용음을 합니다.rgr패키지:

> library(rgr)
> gx.sort.df(dd, ~ -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

매번 열 이름이 다를 수 있는 n개 열에 대한 주문 프로세스를 자동화하고자 할 때 위의 솔루션으로 어려움을 겪었습니다.에서 매우 유용한 기능을 했습니다.psych간단한 방법으로 이를 수행하기 위한 패키지:

dfOrder(myDf, columnIndices)

columnIndices정렬할 순서대로 하나 이상의 열의 인덱스입니다.자세한 내용은 여기:

dfPsych' 패키지의 주문 기능

언급URL : https://stackoverflow.com/questions/1296646/sort-order-data-frame-rows-by-multiple-columns

반응형