Choose one cell per row in data frame
dataframe, matrix, r
Solution
If you are willing to first convert your data.frame to a matrix, you can index elements-to-be-replaced using a two-column matrix. (Beginning with `R-2.16.0`, this will be possible with data.frames directly.) The indexing matrix should have row indices in its first column and column indices in its second column.
Here's an example:
## Create a subset of the your data
set.seed(12008); n <- 6
D <- data.frame(c1=1:n, c2=2*(1:n), c3=3*(1:n))
i <- seq_len(nrow(D)) # vector of row indices
j <- sample(3, n, replace=TRUE) # vector of column indices
ij <- cbind(i, j) # a 2-column matrix to index a 2-D array
# (This extends smoothly to higher-D arrays.)
## Convert it to a matrix
Dmat <- as.matrix(D)
## Replace the elements indexed by 'ij'
Dmat[ij] <- NA
Dmat
# c1 c2 c3
# [1,] 1 2 NA
# [2,] 2 NA 6
# [3,] 3 NA 9
# [4,] 4 8 NA
# [5,] 5 NA 15
# [6,] NA 12 18
Beginning with `R-2.16.0`, you will be able to use the same syntax for dataframes (i.e. without having to first convert dataframes to matrices).
From the `R-devel` `NEWS` file:
Matrix indexing of dataframes by two column numeric indices is now supported for replacement as well as extraction.
Using the current `R-devel` snapshot, here's what that looks like:
D[ij] <- NA
D
# c1 c2 c3
# 1 1 2 NA
# 2 2 NA 6
# 3 3 NA 9
# 4 4 8 NA
# 5 5 NA 15
# 6 NA 12 18
Problem
I have a vector that tells me, for each row in a date frame, the column index for which the value in this row should be updated. ``` > set.seed(12008); n <- 10000; d <- data.frame(c1=1:n, c2=2*(1:n), c3=3*(1:n)) > i <- sample.int(3, n, replace=TRUE) > head(d); head(i) c1 c2 c3 1 1 2 3 2 2 4 6 3 3 6 9 4 4 8 12 5 5 10 15 6 6 12 18 [1] 3 2 2 3 2 1 ``` This means that for rows 1 and 4, c3 should be updated; for rows 2, 3 and 5, c2 should be updated (among others). What is the cleanest way to achieve this in R using vectorized operations, i.e, without `apply` and friends? EDIT: And, if at all possible, without R loops? I have thought about transforming `d` into a matrix and then address the matrix elements using an one-dimensional vector. But then I haven't found a clean way to compute the one-dimensional address from the row and column indexes.