0 Câu hỏi: Làm thế nào để bạn tạo một đối tượng mới và sắp xếp nó theo năm, tên và sự kiện? [bản sao]

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Tôi muốn sắp xếp một data.frame theo nhiều cột. Ví dụ: với data.frame bên dưới tôi muốn sắp xếp theo cột z (giảm dần) sau đó theo cột b (tăng dần):

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
    
1217
  1. Đối với gấu trúc, có thể tìm thấy giải pháp tại đây .
    2019-01-29 23: 27: 57Z
    19 Câu trả lời                              19                         

    Bạn có thể sử dụng order() hoạt động trực tiếp mà không cần dùng đến các công cụ bổ trợ - hãy xem câu trả lời đơn giản hơn này sử dụng một mẹo ngay từ đầu mã 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
    

    Chỉnh sửa khoảng hơn 2 năm sau: Người ta chỉ hỏi làm thế nào để làm điều này theo chỉ mục cột. Câu trả lời là chỉ cần chuyển (các) cột sắp xếp mong muốn cho hàm 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> 
    

    thay vì sử dụng tên của cột (và with() để truy cập trực tiếp /dễ dàng hơn).

        
    1523
    2018-09-21 13: 42: 37Z
    1. @ Dirk Eddelbuettel có một phương pháp đơn giản tương tự cho ma trận không?
      2012-03-27 03: 17: 34Z
    2. Nên hoạt động theo cùng một cách, nhưng bạn không thể sử dụng with. Hãy thử M <- matrix(c(1,2,2,2,3,6,4,5), 4, 2, byrow=FALSE, dimnames=list(NULL, c("a","b"))) để tạo ma trận M, sau đó sử dụng 0600350991111010 >
      2012-03-27 12: 41: 29Z
    3. Đủ dễ dàng: M[order(M[,"a"],-M[,"b"]),], nhưng không thể sử dụng dd[ order(-dd[,4], dd[,1]), ] để đặt tên dựa trên tên.
      2012-10-21 14: 34: 07Z
    4. Tôi có lỗi "đối số không hợp lệ đối với toán tử đơn nguyên" trong khi chạy ví dụ thứ hai.
      2013-01-22 23: 01: 47Z
    5. Lỗi "đối số không hợp lệ đối với toán tử đơn nguyên" xảy ra khi bạn sử dụng dấu trừ với cột ký tự. Giải quyết nó bằng cách gói cột trong with, ví dụ xtfrm.
      2015-03-24 11: 40: 45Z

    Lựa chọn của bạn

    • dd[ order(-xtfrm(dd[,4]), dd[,1]), ] từ order
    • base từ arrange
    • dplyrsetorder từ setorderv
    • data.table từ arrange
    • plyr từ sort
    • taRifx từ orderBy
    • doBy từ sortData

    Hầu hết thời gian bạn nên sử dụng các giải pháp Deducer hoặc dplyr, trừ khi không có phụ thuộc là quan trọng, trong trường hợp đó sử dụng data.table.

    Gần đây tôi đã thêm sort.data.frame vào gói CRAN, làm cho lớp này tương thích như được thảo luận ở đây: Cách tốt nhất để tạo tính nhất quán chung /phương pháp để sắp xếp .data.frame?

    Do đó, với dd dữ liệu.frame, bạn có thể sắp xếp như sau:

    base::order

    Nếu bạn là một trong những tác giả gốc của chức năng này, vui lòng liên hệ với tôi. Thảo luận về phạm vi công cộng có tại đây: http: //chat.stackoverflow.com/transcript/message/1094290#1094290

    Bạn cũng có thể sử dụng chức năng

    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 )
    
    từ arrange() như Hadley đã chỉ ra trong chuỗi trên: plyr

    Điểm chuẩn: Lưu ý rằng tôi đã tải từng gói trong phiên R mới vì có rất nhiều xung đột. Cụ thể là tải gói doBy khiến

    library(plyr)
    arrange(dd,desc(z),b)
    
    trả về "Các đối tượng sau được che dấu từ 'x (vị trí 17)': b, x, y, z" và tải gói Deducer ghi đè lên sort từ Kevin Wright gói. sort.data.frame

    Thời gian trung bình:

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

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

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

    Thời gian trung bình: 1,567

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

    Thời gian trung bình: 862

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

    Thời gian trung bình: 1.694

    Lưu ý rằng doBy mất một chút thời gian để tải gói.

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

    Không thể tải Deducer. Cần bảng điều khiển JGR.

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

    Có vẻ không tương thích với microbenchmark do đính kèm /tách.

    esort <- function(x, sortvar, ...) {
    attach(x)
    x <- x[with(x,order(sortvar,...)),]
    return(x)
    detach(x)
    }
    
    microbenchmark(esort(dd, -z, b),times=1000)
    

     cốt truyện microbenchmark

    (các dòng kéo dài từ phân vị thấp hơn đến phân vị cao hơn, dấu chấm là trung vị)

    Với những kết quả này và cân nhắc sự đơn giản so với tốc độ, tôi phải gật đầu với

    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))
    
    trong gói arrange . Nó có một cú pháp đơn giản và gần như nhanh như các lệnh R cơ sở với các âm mưu phức tạp của chúng. Điển hình là công việc tuyệt vời của Hadley Wickham. Điều duy nhất của tôi với nó là nó phá vỡ danh pháp R tiêu chuẩn nơi các đối tượng sắp xếp được gọi bởi plyr, nhưng tôi hiểu tại sao Hadley lại làm như vậy do các vấn đề được thảo luận trong câu hỏi được liên kết ở trên.

        
    425
    2019-04-12 17: 55: 12Z
    1. + 1 về tính kỹ lưỡng, mặc dù tôi thừa nhận rằng tôi thấy đầu ra sort(object) khá khó đọc ...
      2011-07-31 15: 55: 31Z
    2. Chức năng microbenchmark của ggplot2 ở trên hiện có sẵn là microbenchmark.
      2012-06-01 01: 23: 01Z
    3. @ AriB.Friedman Khoảng thời gian trục y /tỷ lệ là gì?
      2012-07-30 05: 04: 19Z
    4. @ AME xem cách taRifx::autoplot.microbenchmark được sắp xếp trong mẫu. Mặc định được sắp xếp theo tăng dần, vì vậy bạn không bao bọc nó trong b. Tăng dần trong cả hai: desc. Giảm dần trong cả hai: arrange(dd,z,b).
      2013-10-12 10: 16: 56Z
    5. Theo arrange(dd,desc(z),desc(b)): "# LƯU Ý: các hàm plyr KHÔNG bảo toàn hàng.names". Điều này làm cho hàm ?arrange tuyệt vời trở nên tối ưu nếu người ta muốn giữ arrange().
      2014 /03-10 16: 31: 33Z

    Câu trả lời của Dirk rất hay. Nó cũng nêu bật một sự khác biệt chính trong cú pháp được sử dụng để lập chỉ mục row.namess và data.frames:

    data.table

    Sự khác biệt giữa hai cuộc gọi là nhỏ, nhưng nó có thể có những hậu quả quan trọng. Đặc biệt nếu bạn viết mã sản xuất và /hoặc quan tâm đến tính chính xác trong nghiên cứu của mình, tốt nhất là tránh lặp lại không cần thiết các tên biến.

    ## 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)]
    
     giúp bạn làm điều này.

    Đây là một ví dụ về cách lặp lại tên biến có thể khiến bạn gặp rắc rối:

    Hãy thay đổi bối cảnh từ câu trả lời của Dirk và nói rằng đây là một phần của dự án lớn hơn, nơi có rất nhiều tên đối tượng và chúng dài và có ý nghĩa; thay vì data.table, nó được gọi là dd. Nó trở thành:

    quarterlyreport

    Ok, tốt thôi. Không có gì sai với điều đó. Tiếp theo, sếp của bạn yêu cầu bạn đưa báo cáo của quý trước vào báo cáo. Bạn đi qua mã của mình, thêm một đối tượng

    quarterlyreport[with(quarterlyreport,order(-z,b)),]
    
    ở nhiều nơi khác nhau và bằng cách nào đó (làm thế nào trên trái đất?) Bạn kết thúc với điều này: lastquarterlyreport

    Đó không phải là ý của bạn nhưng bạn đã không phát hiện ra vì bạn đã làm nhanh và nó nằm trên một trang có mã tương tự. Mã không bị đổ (không có cảnh báo và không có lỗi) vì R nghĩ rằng đó là ý bạn. Bạn sẽ hy vọng bất cứ ai đọc báo cáo của bạn phát hiện ra nó, nhưng có lẽ họ không biết. Nếu bạn làm việc với các ngôn ngữ lập trình rất nhiều thì tình huống này có thể là tất cả để làm quen. Đó là một "lỗi đánh máy" bạn sẽ nói. Tôi sẽ sửa "lỗi đánh máy" mà bạn sẽ nói với sếp của bạn.

    Trong

    quarterlyreport[with(lastquarterlyreport,order(-z,b)),]
    
    chúng tôi quan tâm đến những chi tiết nhỏ như thế này. Vì vậy, chúng tôi đã làm một cái gì đó đơn giản để tránh gõ tên biến hai lần. Một cái gì đó rất đơn giản. data.table được đánh giá trong khung i rồi, tự động. Bạn không cần dd.

    Thay vì

    with()

    chỉ là

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

    Và thay vì

    dd[order(-z, b)]
    

    chỉ là

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

    Đó là một sự khác biệt rất nhỏ, nhưng nó có thể chỉ cứu cổ bạn một ngày nào đó. Khi cân nhắc các câu trả lời khác nhau cho câu hỏi này, hãy xem xét việc lặp lại các tên biến là một trong những tiêu chí của bạn khi quyết định. Một số câu trả lời có khá nhiều lần lặp lại, một số khác không có.

        
    135
    2012-05-25 21: 42: 51Z
    1. + 1 Đây là một điểm tuyệt vời và nhận được một chi tiết về cú pháp của R thường làm tôi khó chịu. Đôi khi tôi sử dụng
      quarterlyreport[order(-z,b)]
      
      chỉ để tránh phải liên tục nhắc đến cùng một đối tượng trong một cuộc gọi.
      2012-05-25 20: 45: 05Z
    2. Mọi ý tưởng tại sao chúng hoạt động theo những cách khác nhau?
      2012-11-26 07: 21: 21Z
    3. @ naught101 Liệu data.table FAQ 1.9 có trả lời không?
      2012-11-26 08: 04: 59Z
    4. Tôi đoán bạn có thể thêm chức năng subset() mới ở đây, vì chủ đề này là nơi chúng tôi gửi tất cả các bản sao loại setorder.
      2015-01-08 19: 18: 19Z

    Có rất nhiều câu trả lời xuất sắc ở đây, nhưng dplyr đưa ra cú pháp duy nhất mà tôi có thể nhanh chóng và dễ nhớ (và vì vậy bây giờ sử dụng rất thường xuyên):

    order

    Đối với sự cố của OP:

    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)
    
        
    113
    2014 /02-18 21: 29: 25Z
    1. Câu trả lời được chấp nhận không hoạt động khi các cột của tôi là hoặc loại yếu tố (hoặc đại loại như thế) và tôi muốn sắp xếp theo kiểu giảm dần cho cột yếu tố này theo cột số nguyên trong thời trang tăng dần. Nhưng điều này chỉ hoạt động tốt! Cảm ơn bạn!
      2014 /02-22 18: 36: 52Z
    2. Tại sao "chỉ"? Tôi thấy
      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
      
      của data.table khá dễ sử dụng và dễ nhớ.
      2014-03-19 11: 11: 38Z
    3. Đồng ý, không có nhiều giữa hai phương thức đó và dd[order(-z, b)] cũng đóng góp rất lớn cho data.table theo nhiều cách khác. Tôi cho rằng đối với tôi, có thể có một bộ dấu ngoặc (hoặc một loại dấu ngoặc ít hơn) trong trường hợp này làm giảm tải nhận thức xuống một lượng chỉ có thể nhận thấy được.
      2014-03-19 17: 13: 59Z
    4. Đối với tôi, thực tế là R hoàn toàn không phải là khai báo, arrange() thì không.
      2015-05-29 13: 12: 07Z

    Gói R dd[order(-z, b)] cung cấp cả nhanh hiệu quả bộ nhớ sắp xếp thứ tự data.tables với cú pháp đơn giản (một phần trong đó Matt có đã nhấn mạnh khá độc đáo trong câu trả lời của mình ). Đã có khá nhiều cải tiến và cũng là một chức năng mới data.table kể từ đó. Từ setorder(), v1.9.5+ cũng hoạt động với data.frames .

    Trước tiên, chúng tôi sẽ tạo một bộ dữ liệu đủ lớn và điểm chuẩn các phương thức khác nhau được đề cập từ các câu trả lời khác và sau đó liệt kê các tính năng của data.table .

    Dữ liệu:

    setorder()

    Điểm chuẩn:

    Thời gian được báo cáo là từ việc chạy

    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)
    
    trên các chức năng được hiển thị bên dưới. Thời gian được lập bảng dưới đây (theo thứ tự từ chậm nhất đến nhanh nhất). system.time(...)
      Cú pháp
    • 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
      # ------------------------------------------------------------
      
      của data.table ~ 10x nhanh hơn so với các phương thức nhanh nhất (DT[order(...)]), trong khi tiêu thụ cùng một lượng bộ nhớ là 0600350991111010
    • dplyr dplyr ~ 14x nhanh hơn các phương pháp nhanh nhất (data.table), trong khi chỉ cần chỉ thêm 0,4 GB bộ nhớ . setorder() hiện theo thứ tự chúng tôi yêu cầu (vì nó được cập nhật theo tham chiếu).

    tính năng data.table:

    Tốc độ:

      Việc đặt hàng của
    • data.table cực kỳ nhanh chóng vì nó thực hiện đặt hàng cơ số .

    • Cú pháp dplyr được tối ưu hóa nội bộ để sử dụng thứ tự nhanh của data.table . Bạn có thể tiếp tục sử dụng cú pháp cơ sở R quen thuộc nhưng tăng tốc quá trình (và sử dụng ít bộ nhớ hơn).

    Bộ nhớ:

    • Hầu hết thời gian, chúng tôi không yêu cầu data.frame hoặc data.table ban đầu sau khi sắp xếp lại. Đó là, chúng ta thường gán kết quả trở lại cho cùng một đối tượng, ví dụ:

      dat

      Vấn đề là điều này đòi hỏi ít nhất hai lần (2 lần) bộ nhớ của đối tượng ban đầu. Để trở thành bộ nhớ hiệu quả , data.table do đó cũng cung cấp chức năng DT[order(...)].

      DF <- DF[order(...)]
      
      sắp xếp lại data.tables setorder() ( tại chỗ ), mà không tạo thêm bất kỳ bản sao nào. Nó chỉ sử dụng thêm bộ nhớ bằng kích thước của một cột.

    Các tính năng khác:

    1. Nó hỗ trợ setorder(), by reference, integer, logical và thậm chí numeric.

        

      Lưu ý rằng character, bit64::integer64, factor vv .. các lớp đều là các loại Date/POSIXct bên dưới các thuộc tính bổ sung và do đó cũng được hỗ trợ.

    2. Trong cơ sở R, chúng tôi không thể sử dụng integer trên một vectơ ký tự để sắp xếp theo cột đó theo thứ tự giảm dần. Thay vào đó, chúng tôi phải sử dụng numeric.

      Tuy nhiên, trong data.table , chúng tôi chỉ có thể làm, ví dụ: - hoặc -xtfrm(.).

    75
    2017-05-23 10: 31: 37Z
    1. Cảm ơn câu trả lời rất có căn cứ này về data.table. Mặc dù vậy, tôi không hiểu "bộ nhớ tối đa" là gì và cách bạn tính toán nó. Bạn có thể giải thích? Cảm ơn bạn!
      2015-06-30 14: 32: 54Z
    2. Tôi đã sử dụng Dụng cụ - > phân bổ và báo cáo kích thước "Tất cả heap và phân bổ VM".
      2015-06-30 14: 55: 01Z
    3. @ Arun liên kết dụng cụ trong bình luận của bạn đã chết. Muốn đăng cập nhật?
      2016-03-30 15: 03: 24Z
    4. @ MichaelChirico Đây là liên kết đến thông tin về Dụng cụ do Apple tạo ra: developer.apple.com/l Library /content /document /Bang
      2017-07-17 09: 25: 08Z

    Với chức năng này (rất hữu ích) của Kevin Wright , được đăng trong phần mẹo của wiki R, điều này có thể dễ dàng đạt được.

    dat[order(-x)]     
    64
    2016-08-24 14: 49: 59Z
    1. Xem câu trả lời của tôi để đo điểm chuẩn của thuật toán được sử dụng trong hàm này.
      2012-07-12 14: 07: 51Z

    hoặc bạn có thể sử dụng gói doBy

    setorder(dat, -x)     
    35
    2010-01-19 20: 44: 38Z

    Giả sử bạn có số thứ tự giảm dần

    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
    
    library(doBy)
    dd <- orderBy(~-z+b, data=dd)
    
    và bạn muốn sắp xếp nó bằng cách sử dụng cột có tên là data.frame. Gọi số được sắp xếp A x data.frame

    Nếu bạn muốn thứ tự tăng dần, hãy thay thế newdata bằng không có gì. Bạn có thể có một cái gì đó như

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

    trong đó 06003509911111100010     

    33
    2011-05-26 15: 21: 27Z

    Ngoài ra, sử dụng gói Deducer

    "-"     
    26
    2009-08-20 19: 43: 30Z

    nếu SQL tự nhiên đến với bạn, sqldf xử lý ORDER BY như Codd dự định.

        
    26
    2010-03-08 23: 30: 37Z
    1. MJM, cảm ơn bạn đã chỉ ra gói này. Nó cực kỳ linh hoạt và bởi vì một nửa công việc của tôi đã được thực hiện bằng cách lấy từ cơ sở dữ liệu sql, điều đó dễ hơn là học nhiều cú pháp trực quan của R hơn
      2010-07-29 05: 31: 19Z

    Tôi đã tìm hiểu về

    newdata <- A[order(-A$x, A$y, -A$z),]
    
    với ví dụ sau đây khiến tôi bối rối trong một thời gian dài: x

    Lý do duy nhất ví dụ này hoạt động là vì z được sắp xếp theo data.frame, không phải bởi cột có tên A trong data.frame.

    Để thấy điều này, hãy tạo một khung dữ liệu giống hệt nhau bằng cách sử dụng A với các tên cột hơi khác nhau và không sử dụng bất kỳ vectơ nào ở trên:

    x

    Cấu trúc dòng trên cho y không còn hoạt động vì không có vectơ có tên z:

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

    Dòng sau hoạt động vì order sắp xếp trên cột

    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
    
    trong order. vector Age

    Tôi nghĩ rằng điều này đáng để đăng tải vì tôi đã bối rối vì ví dụ này quá lâu. Nếu bài này không được coi là phù hợp với chủ đề tôi có thể remove nó.

    EDIT: ngày 13 tháng 5 năm 2014

    Dưới đây là cách tổng quát sắp xếp khung dữ liệu theo từng cột mà không chỉ định tên cột. Mã dưới đây cho thấy cách sắp xếp từ trái sang phải hoặc phải sang trái. Điều này hoạt động nếu mỗi cột là số. Tôi đã không thử với một cột nhân vật được thêm vào.

    Tôi đã tìm thấy mã Age một hoặc hai tháng trước trong một bài đăng cũ trên một trang web khác, nhưng chỉ sau khi tìm kiếm rộng rãi và khó khăn. Tôi không chắc chắn tôi có thể di dời bài viết đó bây giờ. Chủ đề hiện tại là cú đánh đầu tiên để đặt hàng data frame data vào read.table. Vì vậy, tôi nghĩ rằng phiên bản mở rộng của mã

    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)
    
    đó có thể hữu ích. order     
    15
    2014-05-13 22: 53: 25Z
    1. Cú pháp đó hoạt động nếu bạn lưu trữ dữ liệu của mình trong data.table, thay vì data.frame: age Điều này hoạt động vì tên cột được cung cấp bên trong [ ] ngoặc.
      2013-09 /02 19: 34: 01Z
    2. Tôi không nghĩ rằng downvote là cần thiết ở đây, nhưng tôi không nghĩ rằng điều này bổ sung nhiều vào câu hỏi , đặc biệt là xem xét bộ câu trả lời hiện có, một số trong đó đã nắm bắt được yêu cầu với
      databyage = my.data[order(age),]
      
      để sử dụng order hoặc age.
      2014/02/14 11: 16: 52Z
    3. upvote cho my.data điều này làm cho công việc ngắn của việc sắp xếp khung dữ liệu nhiều màu. Đơn giản chỉ cần
      databyage = my.data[order(my.data$age),]
      
      và một loại thác đẹp sẽ có.
      2016-05-25 04: 28: 53Z

    Câu trả lời của Dirk là tốt nhưng nếu bạn cần sắp xếp để tiếp tục, bạn sẽ muốn áp dụng sắp xếp lại vào tên của khung dữ liệu đó. Sử dụng mã ví dụ:

    do.call     
    14
    2011-05-26 15: 08: 39Z

    Đáp lại nhận xét được thêm vào OP để biết cách sắp xếp theo chương trình:

    Sử dụng data.frameR

    do.call

    dplyr

    Chỉ cần sử dụng

    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
    
    , đây là phiên bản Đánh giá tiêu chuẩn cho require(data.table); my.dt <- data.table(my.data); my.dt[order(age)]. data.frame

    thông tin thêm tại đây: https://cran.r-project.org/web /packages/dplyr/vignettes/nse.html

    Tốt hơn là sử dụng công thức vì nó cũng nắm bắt môi trường để đánh giá biểu thức trong

    data.table

    with     
    14
    2016 /02-05 21: 11: 52Z

    Sắp xếp () trong dplyer là tùy chọn yêu thích của tôi. Sử dụng toán tử đường ống và đi từ khía cạnh quan trọng nhất đến quan trọng nhất

    $     
    8
    2018-10-29 16: 56: 46Z

    Để hoàn thiện: bạn cũng có thể sử dụng chức năng do.call từ gói do.call(sort, mydf.obj):

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

    So sánh hiệu suất:

    dplyr     
    5
    2015-08-07 04: 03: 34Z
    1. lạ khi thêm so sánh hiệu suất khi phương thức của bạn chậm nhất ... dù sao cũng nghi ngờ giá trị của việc sử dụng điểm chuẩn trên 4 hàng data.table
      2016-03-30 14: 58: 47Z

    Giống như các công cụ sắp xếp thẻ cơ học từ lâu, trước tiên, sắp xếp theo khóa quan trọng nhất, sau đó là quan trọng nhất tiếp theo, v.v. p>

    library(dplyr)
    library(data.table)
    

    Bây giờ chúng tôi đã sẵn sàng để thực hiện khóa quan trọng nhất. Sắp xếp ổn định và mọi ràng buộc trong khóa quan trọng nhất đã được giải quyết.

    arrange_

    Đây có thể không phải là nhanh nhất, nhưng nó chắc chắn đơn giản và đáng tin cậy

        
    4
    2015-01-15 04: 28: 25Z

    Một cách khác, sử dụng gói 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)
    
        
    3
    2018-05-01 10: 18: 19Z

    Tôi đã vật lộn với các giải pháp trên khi tôi muốn tự động hóa quy trình đặt hàng của mình cho n cột, có tên cột có thể khác nhau mỗi lần. Tôi đã tìm thấy một chức năng siêu hữu ích từ gói

    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
    
    để thực hiện việc này một cách đơn giản:
    dd1 <- dd %>%
        arrange(z) %>%
        arrange(desc(x))
    

    trong đó sortByCol() là các chỉ mục của một hoặc nhiều cột, theo thứ tự mà bạn muốn sắp xếp chúng. Thêm thông tin tại đây:

    chức năng dfOrder từ gói 'psych'

        
    2
    2018-10-24 22: 32: 43Z

    Chỉ vì mục đích hoàn chỉnh, vì người ta không nói nhiều về việc sắp xếp theo số cột ... Có thể lập luận rằng điều đó thường không được mong muốn (vì thứ tự các cột có thể thay đổi, mở đường cho lỗi ), nhưng trong một số trường hợp cụ thể (ví dụ: khi bạn cần một công việc nhanh chóng được thực hiện và không có nguy cơ cột thay đổi đơn hàng như vậy), đó có thể là điều hợp lý nhất để làm, đặc biệt là khi xử lý số lượng lớn cột.

    Trong trường hợp đó, BBmisc đến giải cứu:

    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
    
        
    2
    2019-04-11 03: 58: 42Z
    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
    
nguồn đặt đây