Reversing the order of duplicated sections in a ve

2020-07-06 04:32发布

Consider the following pre-sorted vector x.

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

order() shows us the order of the vector.

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

Now suppose I want to reverse the order of only the duplicated/repeated values of x, meaning I want to reverse just the 2 3 4 and 7 8 9 sections of o because those are the values repeated in x. Then, the desired result would be

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

What is the best way to do that? Right now I've got the following

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

But that does not give the correct answer here.

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

PS - I am using this to reverse the column order of duplicated column names.

标签: r
2条回答
我欲成王,谁敢阻挡
2楼-- · 2020-07-06 05:00

A base R 1-liner would be using ave to group the ordering by unique values in the original vector, applying rev to reverse the ordering for each group:

ave(order(x), x, FUN=rev)
# [1]  1  4  3  2  5  6  9  8  7 10
查看更多
太酷不给撩
3楼-- · 2020-07-06 05:16

Using 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

Alternatively, you can do:

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

(not entirely sure if there are cases where this could break)

查看更多
登录 后发表回答