for循环创建一系列重复id的块

时间:2016-05-16 06:31:06

标签: r for-loop while-loop repeat

我正在尝试根据类别列(0/1)创建一个新的id(下面数据中的id_2)。如果类别为0,我只需要一个NA,如果这是1,那么我需要为第一组'1'重复1,然后为第二组'1'重复2,依此类推。我需要为每个id_1单独执行此操作。

以下是我的数据示例,我尝试这样做以及输出。 我也尝试在函数中包含一个while循环,但这没有帮助。

任何帮助将不胜感激。

  • 我的数据

      id_1  category    id_2
         1  NA  NA
         1  1   1
         1  1   1
         1  1   1
         1  1   1
         1  0   NA
         1  1   2
         1  1   2
         1  1   2
         1  0   NA
         1  0   NA
         1  1   3
         1  1   3
         1  1   3
         1  0   NA
         2  0   NA
         2  1   1
         2  1   1
         2  0   NA
         2  0   NA
         2  0   NA
         2  1   2
         2  1   2
         2  1   2
         2  1   2
         3  1   1
         3  1   1
         3  1   1
         3  1   1
         3  0   NA
         3  1   2
         3  1   2
         3  0   NA
         3  0   NA
         3  1   3
         3  1   3
         4  0   NA
         4  1   1
         4  1   1
         4  1   1
         4  0   NA
         5  1   1
         5  1   1
         5  1   1
    
  • 我的代码

    my_function <- function(df){
    out <- vector()
    out_2 <- list()
    for(k in unique(df$id_1)){
     dat <- df[df$id_1 == k,]
     i <- 0
     #while(i <= dim(dat)[1]){
      i <- i+1
     for(j in 3: dim(dat)[1]-1){
       out[j] <- (ifelse(dat[j-1, 2] == 1, 
                             ifelse(dat[j, 2] == 1, i, NA),    # yes 1st     ifelse()
                             ifelse(dat[j, 2] == 1, i+1, NA))) # no 1st ifelse()
       out_2[[k]] <- out
       }
     #}
    }
    return(out_2)
    }
    
  • 输出

    #[[1]]
    #[1] NA NA  1  1  1 NA  2  1  1 NA NA  2  1  1
    
    #[[2]]
    #[1] NA  2  1 NA NA NA  2  1  1 NA NA  2  1  1
    
    #[[3]]
    #[1] NA  1  1  1 NA  2  1 NA NA  2 NA  2  1  1
    
    #[[4]]
    #[1] NA  2  1  1 NA  2  1 NA NA  2 NA  2  1  1
    
    #[[5]]
    # [1] NA  1  1  1 NA  2  1 NA NA  2 NA  2  1  1
    

1 个答案:

答案 0 :(得分:3)

我们可以使用data.table。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df1)),按&#39; id_1&#39;分组,我们将run-length-id函数(rleid)应用于逻辑vectorcategory ==0 & !is.na(category)) ,转换0s&#39;到NA(NA^(!i1)*i1)),然后将其更改为factor并获取numeric编码,将其分配(:=)为&#39; id_new&#39;列。

library(data.table)
setDT(df1)[, id_new := {
        i1 <- category*rleid(category==0 & !is.na(category))
         as.numeric(factor(NA^(!i1)*i1))},
         by = id_1]
df1
#    id_1 category id_2 id_new
# 1:    1       NA   NA     NA
# 2:    1        1    1      1
# 3:    1        1    1      1
# 4:    1        1    1      1
# 5:    1        1    1      1
# 6:    1        0   NA     NA
# 7:    1        1    2      2
# 8:    1        1    2      2
# 9:    1        1    2      2
#10:    1        0   NA     NA
#11:    1        0   NA     NA
#12:    1        1    3      3
#13:    1        1    3      3
#14:    1        1    3      3
#15:    1        0   NA     NA
#16:    2        0   NA     NA
#17:    2        1    1      1
#18:    2        1    1      1
#19:    2        0   NA     NA
#20:    2        0   NA     NA
#21:    2        0   NA     NA
#22:    2        1    2      2
#23:    2        1    2      2
#24:    2        1    2      2
#25:    2        1    2      2
#26:    3        1    1      1
#27:    3        1    1      1
#28:    3        1    1      1
#29:    3        1    1      1
#30:    3        0   NA     NA
#31:    3        1    2      2
#32:    3        1    2      2
#33:    3        0   NA     NA
#34:    3        0   NA     NA
#35:    3        1    3      3
#36:    3        1    3      3
#37:    4        0   NA     NA
#38:    4        1    1      1
#39:    4        1    1      1
#40:    4        1    1      1
#41:    4        0   NA     NA
#42:    5        1    1      1
#43:    5        1    1      1
#44:    5        1    1      1