Home > Enterprise >  Using matrix as a lookup table in R
Using matrix as a lookup table in R

Time:10-01

Assume I have a matrix:

> mat1
  A B
A 1 3
B 2 4

And a data frame:

> df
  First Second
1    A    A
2    A    B
3    B    A
4    B    B

How do I do a lookup for the value of First and Second in the matrix?

My desired output in this case is:

> df
  First Second result
1    A    A      1
2    A    B      3
3    B    A      2
4    B    B      4

I figured out that I can do df <- cbind(df, result = diag(mat1[df$First, df$Second])) but is there a way to do it without the diag()? I figured that if I have a long dataframe, then mat1[df$First, df$Second] will make the code run slower if it generates a larger matrix.

CodePudding user response:

Alternative:

df$result <- mat1[as.matrix(df)]
df
#   First Second result
# 1     A      A      1
# 2     A      B      3
# 3     B      A      2
# 4     B      B      4

If df has more columns, you'll need to subset them explicitly, as in

mat1[as.matrix(df[c("First","Second")])]
# [1] 1 3 2 4

CodePudding user response:

We may do this directly from the mat1

as.data.frame(as.table(mat1))

-output

  Var1 Var2 Freq
1    A    A    1
2    B    A    2
3    A    B    3
4    B    B    4

Or convert to a matrix

df$result <- mat1[do.call(cbind, df)]

Or use cbind

df$result <- mat1[cbind(df$First, df$Second)]

-output

> df
  First Second result
1     A      A      1
2     A      B      3
3     B      A      2
4     B      B      4

Or use simplify2array

df$result <- mat1[simplify2array(df)]

data

mat1 <- structure(1:4, .Dim = c(2L, 2L), .Dimnames = list(c("A", "B"), 
    c("A", "B")))
df <- structure(list(First = c("A", "A", "B", "B"), Second = c("A", 
"B", "A", "B")), class = "data.frame", row.names = c("1", "2", 
"3", "4"))

  • Related