首页 > 解决方案 > R如何在每次重置之前创建计数器并使其打印到新列

问题描述

假设我有以下数据框

  df
R1 R2
0  0 
1  1
1  1
0  1
1  1 
0  0
0  1
1  0           
0  0
1  0
1  0
1  1        

我希望创建一个计数器,在每一列中单独计算 '1' 的出现,在每次遇到 0 后重置,并在新列中输出计数。即在第 1 行中,它将在第一步重置,然后计数到 1,然后计数到 2,然后重置,然后计数 1,然后重置、重置等,第 1 列所需的输出为:

  df
R1(Counted) 
N/A   
N/A  
2  
N/A  
1   
N/A  
N/A  
1             
N/A  
N/A  
N/A  
3          

我怀疑我需要类似的东西:

Counter = 0  
for i = 1:nrow(df){
  if (???==1){
    counter=counter+1
  } else {
    counter=0
  }
}  

但我真的没有使用计数器的经验,也不知道如何让它在重置计数器或类似的东西之前连续将其计数打印到新列。

任何帮助深表感谢

标签: rcounter

解决方案


我们可以创建一个函数来帮助data.table::rleid创建基于值的每个变化的组。将所有值变为NA除值为 1 且它是组中的最后一个元素的值。

get_counter <- function(ct) {
   ave(ct, data.table::rleid(ct), FUN = function(x) 
           replace(seq_along(x), x != 1 | seq_along(x) != length(x), NA))
}

此功能可以应用到多个列使用lapply

df[paste0("ct_", names(df))] <- lapply(df, get_counter)
df

#   R1 R2 ct_R1 ct_R2
#1   0  0    NA    NA
#2   1  1    NA    NA
#3   1  1     2    NA
#4   0  1    NA    NA
#5   1  1     1     4
#6   0  0    NA    NA
#7   0  1    NA     1
#8   1  0     1    NA
#9   0  0    NA    NA
#10  1  0    NA    NA
#11  1  0    NA    NA
#12  1  1     3     1

数据

df <- structure(list(R1 = c(0L, 1L, 1L, 0L, 1L, 0L, 0L, 1L, 0L, 1L, 
1L, 1L), R2 = c(0L, 1L, 1L, 1L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 1L
)), class = "data.frame", row.names = c(NA, -12L))

推荐阅读