Reputation:
z=c("abcD9","recde6","7gfbe","dvS1","MNM09")
d=c("abcD9","recde6","abcD9","bgfh123","dvS1")
y <- numeric(length=25)
k<-1
for ( i in 1:5) {
for (j in 1:5) {
a <- (z[i]==d[j])
if( a==TRUE) y[k] <- j else y[k] <- 0
}
k<-k+1
}
I should get the result as 'y' as a vector (1 0 3 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0)
Upvotes: 1
Views: 88
Reputation: 81683
It will work if you move k<-k+1
into the inner loop:
for ( i in 1:5)
{
for (j in 1:5)
{
a <- (z[i]==d[j])
if( a==TRUE)
y[k] <- j
else
y[k] <- 0
k<-k+1
}
}
The result (y
):
[1] 1 0 3 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
By the way: You can obtain the same result with the following commands:
tmp <- sapply(z, function(vec1) !is.na(match(d, vec1)))
y <- numeric(length = length(tmp))
y[unlist(tmp)] <- which(tmp, arr.ind = TRUE)[ , 1]
Upvotes: 2
Reputation: 60924
I'd go for a more vectorized/apply loop approach:
y = do.call('c', lapply(z, function(x) ifelse(x == d, seq_along(d), 0)))
[1] 1 0 3 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
or using expand.grid
:
df = data.frame(expand.grid(d = d, z = z, stringsAsFactors = FALSE),
y = rep(seq_along(d), length(z)))
with(df, ifelse(z == d, y, 0))
Upvotes: 3
Reputation: 59970
You could eliminate the loop and do something vectorised like so:
pos <- t( outer( z , d , FUN = "==" ) )
pos[ pos == TRUE ] <- which( pos , arr.ind = TRUE )[,1]
as.vector(pos)
#[1] 1 0 3 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
Upvotes: 3