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.
When duplicates are removed, the first occurrence of the value in the list is kept, but other identical values are deleted. Because you are permanently deleting data, it's a good idea to copy the original range of cells or table to another worksheet or workbook before removing duplicate values.
We can remove duplicate element in an array by 2 ways: using temporary array or using separate index. To remove the duplicate element from array, the array must be in sorted order. If array is not sorted, you can sort it by calling Arrays. sort(arr) method.
Using std::remove function A simple solution is to iterate the vector, and for each element, we delete all its duplicates from the vector if present. We can either write our own routine for this or use the std::remove algorithm that makes our code elegant. This approach takes constant space but runs in O(n2) time.
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)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With