Reputation: 53
Actually, I want to create a vector "compare" form another vector "data". I want to compare each element in "data" with himself and all the element that follows in the vector. If there is a tie I append 1 to "compare" if not I append 0. For example:
data=c(3,6,7,3)
# I compare 3 to 3, 6, 7 and 3
# Then I compare 6 to 6, 7, and 3
# Then 7 to 7 an 3
# Then 3 to 3 so I get
compare=c(1,0,0,1,1,0,0,1,0,1)
Here is what I have done:
for(i in 1:length(data))
{
for(j in 0:(length(data)-i))
{
if (data[i]==data[i+j])
{
compare=append(compare,1)
}
else
{
compare=append(compare,0)
}
}
}
Is there any way to vectorize this kind of comparison between vectors elements?
Upvotes: 2
Views: 223
Reputation: 132706
We can use dist
:
data=c(3,6,7,3)
res <- as.matrix(dist(data))
res <- res < .Machine$double.eps #find elements with distance of 0
diag(res) <- 1
res[lower.tri(res, TRUE)]
#[1] 1 0 0 1 1 0 0 1 0 1
Upvotes: 3
Reputation: 388907
We can use outer
to compare data
with itself and then extract lower triangular data so that we get output of only the data which follows the current value.
mat <- +(outer(data, data, `==`))
mat[lower.tri(mat, diag = TRUE)]
#[1] 1 0 0 1 1 0 0 1 0 1
Upvotes: 2
Reputation: 5481
You can use sapply on index:
as.numeric(unlist(sapply(1:length(data), function(k) data[k] == data[k:length(data)])))
[1] 1 0 0 1 1 0 0 1 0 1
Current value of index k is compared with all values equal or after k. unlist
allows to concatenate the result of each iteration k. Finally as.numeric
transforms booleans to integers.
Upvotes: 1