3

Suppose I have a table like:

> A = data.table(c(1,2,3),c(4,5,6),c(7,8,9))
> A
    V1 V2 V3
1:  1  4  7
2:  2  5  8
3:  3  6  9

I want to select the first column of the first row, second of the second row and third of the third row, getting the result:

> B
[1] 1 5 9

I've tried something like:

B = A[,c(1,2,3)]

But that does not work. Is it possible to do this? (Obviously in my actual use case the column indexes for each row are going to be variables, but I can guarantee a vector of length equal to the number of rows in the table)

1
  • works for this specific example, but what if the columns I want are c(1,1,2)? Commented Sep 19, 2019 at 20:40

1 Answer 1

2

A vectorized way of subsetting the elements is by providing the row index and column index as a matrix

as.data.frame(A)[cbind(seq_len(nrow(A)), 1:3)]
#[1] 1 5 9

Or convert the .SD to matrix or data.frame and use the row/column index

A[, as.matrix(.SD)[cbind(1:3, 1:3)]]

Or in data.table, pass the i, j index in a loop and extract the elements

A[, unlist(Map(function(i, j) .SD[i, j, with = FALSE], 1:3, 1:3), 
          use.names = FALSE)]
Sign up to request clarification or add additional context in comments.

1 Comment

last one is exactly what I need, thanks! To generalize for anyone looking for this later, the first 1:3 in the @akrun solution is a vector of row ids and the second is a vector of column ids. Both can be replaced by lists, and can feature repetitions or not include every vector, but they must be the same length. For example, A[, unlist(Map(function(i, j) .SD[i, j, with = FALSE], c(2,2,1,3), c(2,3,2,1)), use.names = FALSE)] returns: [1] 5 8 4 3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.