2015-09-22 15 views
9

Hãy xem xét các vector được sắp xếp trước sau x.Đảo ngược thứ tự của các phần được sao chép trong một vector

x <- c(1, 2, 2, 2, 3, 5, 7, 7, 7, 8) 

order() cho chúng ta biết thứ tự của vectơ.

(o <- order(x)) 
# [1] 1 2 3 4 5 6 7 8 9 10 

Bây giờ giả sử tôi muốn đảo ngược thứ tự của chỉ nhân đôi/giá trị lặp đi lặp lại của x, có nghĩa là tôi muốn đảo ngược chỉ 2 3 47 8 9 phần của o vì đó là những giá trị lặp đi lặp lại trong x. Sau đó, kết quả mong muốn sẽ là

[1] 1 4 3 2 5 6 9 8 7 10 

cách tốt nhất để làm điều đó là gì? Ngay bây giờ, tôi đã có những điều sau đây

w <- which(duplicated(x) | duplicated(x, fromLast = TRUE)) 
o[w] <- rev(o[w]) 

Nhưng điều đó không đưa ra câu trả lời đúng ở đây.

o 
# [1] 1 9 8 7 5 6 4 3 2 10 

PS - Tôi đang sử dụng điều này để đảo ngược thứ tự cột của tên cột trùng lặp.

+0

là vector 'x' giả định là luôn luôn ra lệnh để bắt đầu với hoặc một giải pháp sẽ phải khái quát cho có thứ tự 'x's? Ví dụ, kết quả mong muốn của bạn cho 'x <- c (1,3,5,2,7,2,7,2,7,8)' là gì? – aashanand

+0

vòng golf bất cứ ai? 'rev (order (-x))' – rawr

Trả lời

15

Sử dụng data.table v1.9.6:

require(data.table) 
as.data.table(x)[, .(id = rev(.I)), by=x] 
#  x id 
# 1: 1 1 
# 2: 2 4 
# 3: 2 3 
# 4: 2 2 
# 5: 3 5 
# 6: 5 6 
# 7: 7 9 
# 8: 7 8 
# 9: 7 7 
# 10: 8 10 

Ngoài ra, bạn có thể làm:

order(x + sort(runif(length(x)), dec=TRUE)) 
# [1] 1 4 3 2 5 6 9 8 7 10 

(không hoàn toàn chắc chắn nếu có những trường hợp này có thể phá vỡ)

+3

Bạn đã tạo ra 'runif()' như thế nào trên trái đất? Ấn tượng đấy. –

+1

Chữ 'runif() 'là một thủ thuật nhanh và bẩn thực sự ấn tượng. – aashanand

+1

Chữ 'runif' sẽ hoạt động nếu bạn có vectơ có giá trị số nguyên (như Richard làm trong bài toán), nhưng tôi đoán nó có thể làm sai lệch vectơ nếu khoảng cách giữa các phần tử nhỏ hơn 1. – josliber

12

Một cơ sở R 1 lớp lót sẽ sử dụng ave để nhóm thứ tự theo các giá trị duy nhất trong o vector riginal, áp dụng rev để đảo ngược thứ tự cho từng nhóm:

ave(order(x), x, FUN=rev) 
# [1] 1 4 3 2 5 6 9 8 7 10 
+1

Rất hay để xem ave() được sử dụng như áp dụng(). – aashanand

Các vấn đề liên quan