[R] Deleting duplicate rows in a matrix at random
Magnus Torfason
zulutime.net at gmail.com
Thu Jun 3 20:04:50 CEST 2010
> I need to remove all but one of each [row in a matrix], which
> must be chosen at random.
This request (included in full at the bottom), has been unanswered for a
while, but I had the same problem and ended up writing a function to
solve it. I call it "duplicated.random()" and it does exactly the same
thing as the "duplicated()" function apart from the fact that the choice
of which of the duplicated observations gets a FALSE in the result is
random, rather than always being the first. There is no way to specify
any distribution probabilities; each duplicated observation is equally
likely to be chosen.
The implementation is through permuting the original using "sample()",
then running "duplicated()" and finally reversing the permutation on the
result. So the randomization should have "similar properties" as
sample(), probably including reproducibility by setting the random seed
(although haven't tested that explicitly).
The function and some test code are included below. It handles vectors
and matrices for now, but adding other data structures that are handled
correctly by duplicated() should be a simple matter of ensuring that the
indexing is handled correctly in the permutation process. If anyone
makes any improvements to the function, I'd be grateful to be notified.
#############################################################
# This function returns a logical vector, the elements of which
# are FALSE, unless there are duplicated values in x, in which
# case all but one elements are TRUE (for each set of duplicates).
# The only difference between this function and the duplicated()
# function is that rather than always returning FALSE for the first
# instance of a duplicated value, the choice of instance is random.
duplicated.random = function(x, incomparables = FALSE, ...)
{
if ( is.vector(x) )
{
permutation = sample(length(x))
x.perm = x[permutation]
result.perm = duplicated(x.perm, incomparables, ...)
result = result.perm[order(permutation)]
return(result)
}
else if ( is.matrix(x) )
{
permutation = sample(nrow(x))
x.perm = x[permutation,]
result.perm = duplicated(x.perm, incomparables, ...)
result = result.perm[order(permutation)]
return(result)
}
else
{
stop(paste("duplicated.random() only supports vectors",
"matrices for now."))
}
}
#############################################################
# Test code for vector case
x = sample(1:5,10,T)
d = duplicated(x)
r = duplicated.random(x)
cbind(x,d,r)
x[!d]
x[!r]
# Test code for matrix case
x = matrix(sample(1:2,30,T), ncol=3)
d = duplicated(x)
r = duplicated.random(x)
cbind(x,d,r)
#############################################################
On 3/24/2010 11:44 AM, jeff.m.ewers wrote:
>
> Hello,
>
> I am relatively new to R, and I've run into a problem formatting my data for
> input into the package RankAggreg.
>
> I have a matrix of gene titles and P-values (weights) in two columns:
>
> KCTD12 4.06904E-22
> UNC93A 9.91852E-22
> CDKN3 1.24695E-21
> CLEC2B 4.71759E-21
> DAB2 1.12062E-20
> HSPB1 1.23125E-20
> ...
>
> The data contains many, many duplicate gene titles, and I need to remove all
> but one of each, which must be chosen at random. I have looked for quite
> some time, and I've been unable to find a way to do this. Any help would be
> greatly appreciated!
>
> Thanks,
>
> Jeff
More information about the R-help
mailing list