r - 如何基于因子组合将行索引添加到数据框

use*_*603 6 r

我有一个这样的数据框:

df <- data.frame(
    Dim1 = c("A","A","A","A","A","A","B","B"),
    Dim2 = c(100,100,100,100,200,200,100,200),
    Value = sample(1:10, 8)
        )

  Dim1 Dim2 Value
1    A  100     3
2    A  100     6
3    A  100     7
4    A  100     4
5    A  200     8
6    A  200     9
7    B  100     2
8    B  200    10
Run Code Online (Sandbox Code Playgroud)

(Value列只是为了说明每一行都是一个数据点;实际值并不重要.)最后我想要做的是 Dim1和Dim2定义的子集中将值与其索引进行绘制.出于这个原因,我认为需要附加一个包含索引的新列,它们看起来像这样(在行之间添加空白行以明确子集的内容):

  Dim1 Dim2 Value Index
1    A  100     1     1
2    A  100     9     2
3    A  100     4     3
4    A  100    10     4

5    A  200     7     1
6    A  200     3     2

7    B  100     5     1

8    B  200     8     1
Run Code Online (Sandbox Code Playgroud)

我如何在R中优雅地做到这一点?我来自Python,我的默认方法是对Dim1和Dim2的组合进行循环,跟踪每个组中的行数,并将到目前为止遇到的最大值分配给每一行.我一直想弄明白,但我的矢量很弱.

42-*_*42- 5

这可能看起来像作弊,因为我将一个向量传递给一个函数,然后我完全忽略它除了得到它的长度:

 df$Index <- ave( 1:nrow(df), df$Dim1, factor( df$Dim2), FUN=function(x) 1:length(x) )
Run Code Online (Sandbox Code Playgroud)

ave函数返回与第一个参数长度相同的向量,但在第一个参数和名为参数之间的所有因子定义的类别中计算FUN.(我经常忘记将"FUN ="放入我的函数中并获得一条神秘的错误消息unique() applies only to vectors,因为它试图确定一个匿名函数拥有多少个唯一值并且它失败了.

实际上还有另一种更紧凑的表达方式,function(x) 1:length(x)使用seq_along函数whch可能更安全,因为如果传递长度为零的向量将会失败,而匿名函数形式将通过返回1:0而不是不正确地失败numeric(0):

ave( 1:nrow(df), df$Dim1, factor( df$Dim2), FUN=seq_along )
Run Code Online (Sandbox Code Playgroud)


edd*_*ddi 5

在这里,使用data.table

library(data.table)
df <- data.table(
    Dim1 = c("A","A","A","A","A","A","B","B"),
    Dim2 = c(100,100,100,100,200,200,100,200),
    Value = sample(1:10, 8)
        )

df[, index := seq_len(.N), by = list(Dim1, Dim2)]
Run Code Online (Sandbox Code Playgroud)