Reputation: 323
Yes, loops are very slow in R. But I don't know how to replace loop with *pply in code like this, where every matrix cell is calculated against all other cells. The result is matrix again:
for(i in 1:ncol(matrix)) {
for(j in 1:ncol(matrix)) {
result[i,j] <- function(set[i]),set[j]))
}
}
Can you help please?
EDIT:
The matrix looks like this:
A B C D E F
A 0 0 1 0 1 0
B 1 0 0 0 1 0
C 1 0 0 1 0 0
D 0 0 0 0 0 1
E 1 1 0 1 0 1
F 0 0 1 0 1 0
The function I want to apply is
getCosine <- function(x,y)
{
this.cosine <- sum(x*y) / (sqrt(sum(x*x)) * sqrt(sum(y*y)))
return(this.cosine)
}
In loop it looks like this:
result[i,j] <- getCosine(as.matrix(a[i]), as.matrix(a[j]))
Upvotes: 0
Views: 609
Reputation: 59345
Assuming that you want to find the cosine of the angle between every column and every other column you could use something like this:
sapply(df, function(y) sapply(df,get.cos,y))
Here's the full code.
df = read.table(h=T,row.names=1,text="
A B C D E F
A 0 0 1 0 1 0
B 1 0 0 0 1 0
C 1 0 0 1 0 0
D 0 0 0 0 0 1
E 1 1 0 1 0 1
F 0 0 1 0 1 0")
get.cos <- function(x,y) sum(x*y)/sqrt(sum(x*x)*sum(y*y))
# using loops
result.1 <- matrix(NA, nc=ncol(df),nr=nrow(df))
for(i in 1:ncol(df)) {
for(j in 1:ncol(df)) {
result.1[i,j] <- get.cos(df[,i],df[,j])
}
}
result.1
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 1.0000000 0.5773503 0.0000000 0.8164966 0.3333333 0.4082483
# [2,] 0.5773503 1.0000000 0.0000000 0.7071068 0.0000000 0.7071068
# [3,] 0.0000000 0.0000000 1.0000000 0.0000000 0.8164966 0.0000000
# [4,] 0.8164966 0.7071068 0.0000000 1.0000000 0.0000000 0.5000000
# [5,] 0.3333333 0.0000000 0.8164966 0.0000000 1.0000000 0.0000000
# [6,] 0.4082483 0.7071068 0.0000000 0.5000000 0.0000000 1.0000000
# using sapply(...)
result.2 <- sapply(df, function(y) sapply(df,get.cos,y))
result.2
# A B C D E F
# A 1.0000000 0.5773503 0.0000000 0.8164966 0.3333333 0.4082483
# B 0.5773503 1.0000000 0.0000000 0.7071068 0.0000000 0.7071068
# C 0.0000000 0.0000000 1.0000000 0.0000000 0.8164966 0.0000000
# D 0.8164966 0.7071068 0.0000000 1.0000000 0.0000000 0.5000000
# E 0.3333333 0.0000000 0.8164966 0.0000000 1.0000000 0.0000000
# F 0.4082483 0.7071068 0.0000000 0.5000000 0.0000000 1.0000000
Upvotes: 3