3

I've the following data.table

structure(list(xi = c(1, 1, 1, 2, 2, 2, 3, 3, 3), yi = c(1, 2, 
3, 1, 2, 3, 1, 2, 3), flag = c(0, 0, 0, 0, 0, 0, 0, 0, 0)), .Names = c("xi", 
"yi", "flag"), row.names = c(NA, -9L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x11a1a78>)

I also have a 3x3 matrix as below.

structure(c(1, 1, 0.4, 1, 0, 0, 1, 0, 0.2), .Dim = c(3L, 3L))

I want to assign a third column to the data.table flag such that if the element in the matrix represented by the xi row and yi column is less than 1, then flag = 1 else 0. I wrote a function for this,

func <- function (x, y, m) {
if (m[x, y] < 1) {
    return(1)
}
else {
    return(0)
}
}

However, if I try

y[,flag := func(xi,yi,m)]

my flag values are always 0. Could someone point out what I'm doing wrong here? Thanks in advance.

broccoli
  • 4,738
  • 10
  • 42
  • 54

1 Answers1

3

You don't need a custom function...

dt[ , flag := as.integer( m[cbind(xi,yi)] < 1 ) ]

You do need to be careful to index the matrix in the correct way (using cbind(...) rather than [,] form of indexing).

Simon O'Hanlon
  • 58,647
  • 14
  • 142
  • 184
  • How would that work if we wanted to update the matrix instead of reading it? This doesn't work: dt[ , m[cbind(xi,yi)]<-flag ) ] and DT[ ,{m[cbind(xi,yi)<-flag NULL}], neither. Theoretically you can execute any command in the j part. – Picarus Mar 19 '15 at 06:17