【问题标题】:Adding an repeated index for factors in data frame为数据框中的因子添加重复索引
【发布时间】:2011-05-27 10:28:26
【问题描述】:

我有一个数据框,我想在其中添加一个索引,例如1...n 用于我的数据框中的每个因素。这是一个包含一些虚拟数据的示例。

factor
a        
a         
a         
a        
a        
b        
b        
b        
b        
b
c
c
c
c

我想添加一个额外的列,分别为每个因子添加索引 1 到 n。结果数据框如下所示:

factor  index
a        1
a        2 
a        3 
a        4
a        5
b        1
b        2
b        3
b        4
b        5 
c        1
c        2
c        3
c        4

谁能解释一下怎么做?提前致谢。

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    你可以使用ave函数:

    your_data <- data.frame(
         factor=factor(rep(letters[1:3], times = c(5,5,4)))
    )
    your_data$index <- ave(rep(NA, nrow(your_data)), your_data$factor, FUN=seq_along)
    

    【讨论】:

    • +1 在这里很好地使用了ave()并且它在数据未排序时工作。
    【解决方案2】:

    一种方法是:

    unlist(lapply(split(x, x), seq_along))
    

    其中x 是您作为向量的因子。

    R> x <- factor(rep(letters[1:3], times = c(5,5,4))) ## your data
    R> data.frame(factor = x, index = unlist(lapply(split(x, x), seq_along), 
    +             use.names = FALSE))
       factor index
    1       a     1
    2       a     2
    3       a     3
    4       a     4
    5       a     5
    6       b     1
    7       b     2
    8       b     3
    9       b     4
    10      b     5
    11      c     1
    12      c     2
    13      c     3
    14      c     4
    

    另一种方式,类似的主题是使用table()seq_len()

    unlist(sapply(table(x), seq_len), use.names = FALSE)
    

    另一种方法是通过rle()使用游程编码:

    R> rle(as.character(x))$lengths
    [1] 5 5 4
    

    我们可以将其插入sapply() 代码而不是table() 调用:

    R> unlist(sapply(rle(as.character(x))$lengths, seq_len), use.names = FALSE)
     [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4
    

    【讨论】:

    • 如果x 混合使用,此方法将失败。尝试x&lt;-sample(x) 并运行您的代码。
    • @Marek 鉴于 OP 显示了已排序的数据,我认为我提供的答案没有任何问题。还是我们应该猜测 OP 现在真正想要什么? ;-) 无论如何,x &lt;- sort(sample(x)) 会解决问题 :-)
    • 谢谢,我使用了 sapply 选项,使用了 inside 函数,它运行良好。干杯。
    【解决方案3】:

    试试下面的函数:

     facSeq <- function(x){
         x.l <-length(x)
         x.f.l <- length(levels(x))
         sapply(1:x.f.l,function(y) cumsum(as.integer(x)%in%y))[1:x.l+x.l*(as.integer(x)-1)]
     }
    

    测试:

    fac1 <- factor(rep(letters[1:3],each=5))
    
    > data.frame(fac1,index=facSeq(fac1))
       fac1 index
    1     a     1
    2     a     2
    3     a     3
    4     a     4
    5     a     5
    6     b     1
    7     b     2
    8     b     3
    9     b     4
    10    b     5
    11    c     1
    12    c     2
    13    c     3
    14    c     4
    15    c     5
    

    更有趣的例子:

    fac2 <- factor(sample(letters[1:5],20,replace=T))
    
    > data.frame(fac2,index=facSeq(fac2))
       fac2 index
    1     a     1
    2     a     2
    3     d     1
    4     b     1
    5     a     3
    6     e     1
    7     e     2
    8     a     4
    9     c     1
    10    e     3
    11    b     2
    12    d     2
    13    b     3
    14    e     4
    15    e     5
    16    d     3
    17    c     2
    18    e     6
    19    b     4
    20    d     4
    

    【讨论】:

      【解决方案4】:

      在基础 R 中使用 sequencetable

      df$index <- sequence(table(df$factor))
      
         # factor index
      # 1       a     1
      # 2       a     2
      # 3       a     3
      # 4       a     4
      # 5       a     5
      # 6       b     1
      # 7       b     2
      # 8       b     3
      # 9       b     4
      # 10      b     5
      # 11      c     1
      # 12      c     2
      # 13      c     3
      # 14      c     4
      

      数据

      df <- data.frame(factor=factor(rep(letters[1:3], times = c(5,5,4))))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        • 2016-09-02
        • 2014-06-24
        • 2017-11-20
        • 1970-01-01
        • 2020-02-19
        相关资源
        最近更新 更多