0

I have a data.frame with two columns. One indicating objects, the other one indicates if the objects are within some group. How can I create an adjacency matrix without writing a loop?

data("mtcars")
testdf <- data.frame(names=as.character(row.names(mtcars)[1:5]),
                 ingroup=0)

set.seed(123)
testdf$ingroup[testdf$names%in%row.names(mtcars)[sample(length(row.names(mtcars)[1:5]), 2)]] <- 1

testdf
              names ingroup
1         Mazda RX4       0
2     Mazda RX4 Wag       1
3        Datsun 710       0
4    Hornet 4 Drive       1
5 Hornet Sportabout       0

EDIT: The desired output should be a matrix indicating if objects are within a certain group:

data.frame(x1=c(0,0,0,0,0),
       x2=c(0,1,0,0,1),
       x3=c(0,0,0,0,0),
       x4=c(0,0,0,0,0),
       x5=c(0,1,0,0,1))
colnames(output) <- c("Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Mazda RX4","Mazda RX4 Wag")
rownames(output) <- c("Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Mazda RX4","Mazda RX4 Wag")

output
                  Datsun 710 Hornet 4 Drive Hornet Sportabout Mazda RX4 Mazda RX4 Wag
Datsun 710                 0              0                 0         0             0
Hornet 4 Drive             0              1                 0         0             1
Hornet Sportabout          0              0                 0         0             0
Mazda RX4                  0              0                 0         0             0
Mazda RX4 Wag              0              1                 0         0             1

Thanks, Thomas

emilliman5
  • 5,816
  • 3
  • 27
  • 37
Thomas
  • 1,392
  • 3
  • 22
  • 38
  • Not sure why you said that my solution is not giving the expected output. According to your example and expected output, it is giving the same – akrun Jul 07 '17 at 09:53
  • no I made the same mistake I intended to avoid. sorry. As you can see in `testdf` the Datsun 710 shouldn't get a `1`. By using `tcrossprod(tbl)` we get exactly the opposite of what I want (because if a zero hits, it gets a one). By using `tcrossprod(tbl[,2])` I get what I want. Right? Sorry for the confusion. – Thomas Jul 07 '17 at 10:03

1 Answers1

0

You just take the cross product of the ingroup variable:

res <- tcrossprod(testdf$ingroup)
rownames(res) <- testdf$names
colnames(res) <- testdf$names
res

# Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout
# Mazda RX4                 0             0          0              0                 0
# Mazda RX4 Wag             0             1          0              1                 0
# Datsun 710                0             0          0              0                 0
# Hornet 4 Drive            0             1          0              1                 0
# Hornet Sportabout         0             0          0              0                 0
emilliman5
  • 5,816
  • 3
  • 27
  • 37