在数据框中每行选择一个单元格

时间:2012-06-05 09:01:19

标签: r matrix dataframe

我有一个向量,告诉我,对于日期框架中的每一行,应该更新此行中值的列索引。

> 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

这意味着对于第1行和第4行,应更新c3;对于第2,3和5行,应更新c2(以及其他)。使用矢量化操作在R中实现这一目标的最简洁方法是什么,即没有apply和朋友? 编辑:并且,如果可能的话,没有R循环?

我考虑过将d转换为矩阵,然后使用一维向量来处理矩阵元素。但后来我没有找到一种从行和列索引计算一维地址的简洁方法。

3 个答案:

答案 0 :(得分:4)

使用您的示例数据,并且仅使用前几行(DI),您可以轻松地通过矩阵做您想要的事情。

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列的开头。然后我们添加行索引以获取I列中第n个元素的索引。

使用此我们只需使用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

答案 1 :(得分:3)

这是一种方式:

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

答案 2 :(得分: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开始,您将能够对数据帧使用相同的语法(即无需先将数据帧转换为矩阵)。

来自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