Select a cell in a row in a data frame

I have a vector that tells me for each row in the date frame the index of the column for which the value in this row needs to 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 lines 1 and 4, c3 needs to be updated; for lines 2, 3 and 5, c2 should be updated (among other things). What is the cleanest way to achieve this in R using vectorized operations, i.e. Without applyand friends? EDIT: And, if at all possible, without R-loops?

I thought about converting dto a matrix, and then turned to matrix elements using a one-dimensional vector. But then I did not find a clean way to calculate a one-dimensional address from row and column indices.

+5
source share
3

data.frame , . ( R-2.16.0, data.frames.) .

:

## 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

R-2.16.0, dataframes (.. ).

R-devel NEWS:

, .

R-devel, :

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
+3

(D I ) , , , .

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)
## just work with small subset
D <- head(d)
I <- head(i)

D :

dmat <- data.matrix(D)

, , I. , ( I), seq_along(I), 1:6. :

(I - 1) * nrow(D) + seq_along(I)

((I - 1) * nrow(D)) ( 6) I th. , n- I th.

, dmat "[", . "[" ("[<-") . NA, , :

> dmat
  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
> dmat[(I - 1) * nrow(D) + seq_along(I)] <- 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
+4

Here is one way:

d[which(i == 1), "c1"] <- "one"
d[which(i == 2), "c2"] <- "two"
d[which(i == 3), "c3"] <- "three"

   c1  c2    c3
1   1   2 three
2   2 two     6
3   3 two     9
4   4   8 three
5   5 two    15
6 one  12    18
+3
source

All Articles