识别R中的模式,相应地计数和分配值

时间:2018-06-20 02:06:27

标签: r loops pattern-matching

我是R的新手,所以这个问题可能很基本。 我的数据中有一列类似于4 4 4 4 7 7 7 13 13 13 13 13 13 13 13 4 4 7 7 7 13 13 13 13 13 13 13 13 4 4 .....

一个4 ... 7 ... 13 ...的循环被视为一个完整的运行,我将为每个运行分配一个运行编号(1、2、3 ...)。

每个值(4、7、13)重复的次数也不是固定的,一次运行中的总行数也不是固定的。运行总数未知(但通常在60-90之间)。 (4,7,13)的顺序是固定的。

我在此处附加了当前代码。它工作正常,但是当大约有几百万行数据时,它需要一两分钟。我知道在R中实际上不建议在for循环中增加向量,所以我想问问是否有人对此有更好的解决方案。

可以使用以下代码生成示例数据,还可以使用以下示例代码生成所需的输出。

#Generates sample data
df <- data.frame(Temp = c(sample(50:250, 30)), Pres = c(sample(500:1000, 30)), 
             Message = c(rep(4, 3), rep(7, 2), rep(13, 6), rep(4, 4), rep(7, 1), rep(13, 7), rep(4, 3), rep(7, 4)))

当前解决方案

prev_val = 0
Rcount = 1
Run_Count = c()
for (val in df$Message)
{
  delta = prev_val - val
  if((delta == 9))
  Rcount = Rcount + 1
  prev_val = val
  Run_Count = append(Run_Count, Rcount)
}
df$Run = Run_Count

所需的输出:

226 704 4  1
138 709 4  1
136 684 4  1 
 57 817 7  1
187 927 7  1
190 780 13 1
152 825 13 1
126 766 13 1
202 855 13 1
214 757 13 1
172 922 13 1
 50 975 4  2
159 712 4  2
212 802 4  2
181 777 4  2
102 933 7  2
165 753 13 2
 67 962 13 2
119 631 13 2

数据帧稍后将由运行编号分割,但会根据值(即

)进行分类
... 4 1 
... 4 1 
... 4 1 
... 4 1 
... 4 2 
... 4 2 
... 4 2 
... 4 3
.....

2 个答案:

答案 0 :(得分:2)

我不确定这是否有所改善,但是它使用rle游程长度编码功能来确定每次游程中每个重复的长度。

df <- data.frame(Temp = c(sample(50:250, 30)), Pres = c(sample(500:1000, 30)), 
                 Message = c(rep(4, 3), rep(7, 2), rep(13, 6), rep(4, 4), rep(7, 1), rep(13, 7), rep(4, 3), rep(7, 4)))

rleout<-rle(df$Message)
#find the length of the runs and create the numbering
runcounts<-ceiling(length(rleout$lengths)/3)
runs<-rep(1:runcounts, each=3)    

#need to trim the length of run numbers for cases where there is not a  
#   full sequence, as in the test case.
rleout$values<-runs[1:length(rleout$lengths)]

#create the new column
df$out<-inverse.rle(rleout)

我确定有人可以使用数据表来演示和演示更好,更快的方法。

答案 1 :(得分:2)

易于使用:

df$runID <- cumsum(c(-1,diff(df$Message)) < 0)

#    Temp Pres Message runID
# 1   174  910       4     1
# 2   181  612       4     1
# 3   208  645       4     1
# 4    89  601       7     1
# 5   172  812       7     1
# 6   213  672      13     1
# 7   137  848      13     1
# 8   153  833      13     1
# 9   127  591      13     1
# 10  243  907      13     1
# 11  146  599      13     1
# 12  151  567       4     2
# 13  139  855       4     2
# 14  147  793       4     2
# 15  227  533       4     2
# 16  241  959       7     2
# 17  206  948      13     2
# 18  236  875      13     2
# 19  133  537      13     2
# 20   70  688      13     2
# 21  218  528      13     2
# 22  244  927      13     2
# 23  161  697      13     2
# 24  177  572       4     3
# 25  179  911       4     3
# 26  192  559       4     3
# 27   60  771       7     3
# 28  245  682       7     3
# 29  196  614       7     3
# 30  171  536       7     3