scuerda
scuerda

Reputation: 525

Transforming a table of Nearest Neighbor Distances into a Matrix

I have a data frame generated from computing nearest neighbor (K=2) using the RANN package. I would like to transform this data into a matrix with values of 0,1,2 for each cell with 0 = not neighbor, 1=nearest neighbor, 2=2nd nearest neighbor.

The data frame has two columns, the first column is the ID of the 1st NN, the second column is the ID of the 2nd NN. The rows correspond to the ID of the point from which the NN were calculated.

Is there an existing routine to easily to this sort of transformation?

Thanks

Upvotes: 2

Views: 698

Answers (2)

juba
juba

Reputation: 49033

Another possibility, but not especially prettier. Thanks to @user1317221_G for the sample data !

NNdf <- data.frame(NN1=c(1,2,4,3),NN2=c(2,3,1,2))
NNdf$origin <- as.numeric(rownames(NNdf))
NNdf

  NN1 NN2 origin
1   1   2      1
2   2   3      2
3   4   1      3
4   3   2      4

res <- matrix(0,nrow(NNdf),nrow(NNdf))
res[as.matrix(NNdf[,c("origin","NN1")])] <- 1
res[as.matrix(NNdf[,c("origin","NN2")])] <- 2
res

     [,1] [,2] [,3] [,4]
[1,]    1    2    0    0
[2,]    0    1    2    0
[3,]    2    0    0    1
[4,]    0    2    1    0

Upvotes: 0

user1317221_G
user1317221_G

Reputation: 15441

Based on the limited idea you have given, here is, I think, an unpretty solution:

 NNdf <- data.frame(NN1=c(1,2,4),NN2=c(2,3,1)) # make up some data
 NNdf$origin <- rownames(NNdf)

 NNdf
#  NN1 NN2 origin
#1   1   2      1
#2   2   3      2
#3   4   1      3


 library(reshape2)
 hold <- melt(NNdf, id = "origin")
 hold
#  origin variable value
#1      1      NN1     1
#2      2      NN1     2
#3      3      NN1     4
#4      1      NN2     2
#5      2      NN2     3
#6      3      NN2     1


 hold2 <- dcast(hold, origin~value, value.var="variable")

 hold2[hold2 == "NN1"]  <- 1
 hold2[hold2 == "NN2"]  <- 2
 hold2[is.na(hold2) ]   <- 0

 hold2
#  origin 1 2 3 4
#1      1 1 2 0 0
#2      2 0 1 2 0
#3      3 2 0 0 1

(this might rely on apply(hold2,1,as.numeric) afterwards)

Upvotes: 2

Related Questions