này đã đưa ra trong danh sách plyr
gửi thư một khi trở lại (nêu ra bởi @kohske không kém) và điều này là một giải pháp được cung cấp bởi Peter Meilstrup đối với trường hợp có giới hạn:
#Peter's version used a function gensym to
# create the col name, but I couldn't track down
# what package it was in.
keeping.order <- function(data, fn, ...) {
col <- ".sortColumn"
data[,col] <- 1:nrow(data)
out <- fn(data, ...)
if (!col %in% colnames(out)) stop("Ordering column not preserved by function")
out <- out[order(out[,col]),]
out[,col] <- NULL
out
}
#Some sample data
d <- structure(list(g = c(2L, 2L, 1L, 1L, 2L, 2L), v = c(-1.90127112738315,
-1.20862680183042, -1.13913266070505, 0.14899803094742, -0.69427656843677,
0.872558638137971)), .Names = c("g", "v"), row.names = c(NA,
-6L), class = "data.frame")
#This one resorts
ddply(d, .(g), mutate, v=scale(v)) #does not preserve order of d
#This one does not
keeping.order(d, ddply, .(g), mutate, v=scale(v)) #preserves order of d
Xin đừng đọc thread cho Hadley lưu ý về lý do tại sao chức năng này có thể không đủ chung để cuộn vào ddply
, đặc biệt vì chức năng này có thể áp dụng trong trường hợp của bạn vì bạn có khả năng trả về ít hàng hơn với mỗi phần.
Edited để bao gồm một chiến lược đối với trường hợp tổng quát hơn
Nếu ddply
được xuất ra cái gì mà được sắp xếp theo một thứ tự mà bạn không thích, bạn có hai lựa chọn: xác định thứ tự mong muốn trên các biến tách trước sử dụng các yếu tố được sắp xếp hoặc tự sắp xếp đầu ra sau khi thực tế.
Ví dụ, hãy xem xét các dữ liệu sau:
d <- data.frame(x1 = rep(letters[1:3],each = 5),
x2 = rep(letters[4:6],5),
x3 = 1:15,stringsAsFactors = FALSE)
sử dụng chuỗi, cho bây giờ. ddply
sẽ sắp xếp các đầu ra, mà trong trường hợp này sẽ kéo theo mặc định đặt hàng từ vựng:
> ddply(d,.(x1,x2),summarise, val = sum(x3))
x1 x2 val
1 a d 5
2 a e 7
3 a f 3
4 b d 17
5 b e 8
6 b f 15
7 c d 13
8 c e 25
9 c f 27
> ddply(d[sample(1:15,15),],.(x1,x2),summarise, val = sum(x3))
x1 x2 val
1 a d 5
2 a e 7
3 a f 3
4 b d 17
5 b e 8
6 b f 15
7 c d 13
8 c e 25
9 c f 27
Nếu khung dữ liệu kết quả không được kết thúc trong "đúng" trật tự, nó có thể là vì bạn thực sự muốn có một số những biến được đặt hàng yếu tố. Giả sử chúng ta thực sự muốn x1
và x2
ra lệnh như vậy:
d$x1 <- factor(d$x1, levels = c('b','a','c'),ordered = TRUE)
d$x2 <- factor(d$x2, levels = c('d','f','e'), ordered = TRUE)
Bây giờ khi chúng tôi sử dụng ddply
, các loại kết quả sẽ được như chúng tôi dự định:
> ddply(d,.(x1,x2),summarise, val = sum(x3))
x1 x2 val
1 b d 17
2 b f 15
3 b e 8
4 a d 5
5 a f 3
6 a e 7
7 c d 13
8 c f 27
9 c e 25
Các đạo đức của câu chuyện ở đây là nếu ddply
là xuất ra một thứ gì đó theo thứ tự bạn không có ý định, đó là một dấu hiệu tốt cho thấy bạn nên sử dụng các yếu tố đặt hàng cho các biến mà bạn đang chia nhỏ.
Điều này không liên quan gì đến 'write.table'; tiêu đề phải được thay đổi. –