R需要基于ID和时间偏移的非唯一第二列分布来比较R中的行

R需要基于ID和时间偏移的非唯一第二列分布来比较R中的行,r,R,我需要比较第一个值和最后一个值(取差值)。我试着把用户(C/A)列放在后面。把人1想象成C,把人2想象成A 问题是,从C到C到C等有不同的周期,没有上限,所以我需要一些足够灵活的东西。有两个周期,我可以只挂接序列并连接,但这只是一个特例,对我一点帮助都没有。我需要确定的是每个时段从第一个C到最后一个C的时间偏移分布,因此每个ID可能有多个C->C->C->etc偏移,因此我无法通过将ID和序列以及用户连接到组来创建唯一标识符,如果Cs的每个时段都有一个唯一的ID,这将非常好。当C=C时,有一个假

我需要比较第一个值和最后一个值(取差值)。我试着把用户(C/A)列放在后面。把人1想象成C,把人2想象成A

问题是,从C到C到C等有不同的周期,没有上限,所以我需要一些足够灵活的东西。有两个周期,我可以只挂接序列并连接,但这只是一个特例,对我一点帮助都没有。我需要确定的是每个时段从第一个C到最后一个C的时间偏移分布,因此每个ID可能有多个C->C->C->etc偏移,因此我无法通过将ID和序列以及用户连接到组来创建唯一标识符,如果Cs的每个时段都有一个唯一的ID,这将非常好。当C=C时,有一个假人帮助识别。如果我能用虚拟的差值求和,我也能得到我所需要的。例如,第2行和第3行中的17+15=C-C-C期间的时间差,我需要所有事件的时间差

以下是迄今为止的数据示例:

数据:

 ID    Sequen_num    user      time_shift  userlag1  time_shift2  difference    Dummy(user= C userlag1=C )  

1         1             A           1           C            15        14            0  
1         2             C          15           C            32        17            1  
1         3             C          32           C            47        15            1  
1         4             C          47           A            65        18            0
1         5             A          65           C            80        15            0
1         6             C          80           C            110       30            1
1         7             C          110          A            120       10            0
1         8             A          120  
如果我有这样的东西,那将非常简单(基本上是一种识别每个ID中每个块的方法):


这将创建一个排序向量,该向量在用户列的连续值运行中具有相同的值。假设此当前未命名的数据帧的名称为“dat”:

ct <- 1; for( i in seq_along(dat$user)[-1] ) { if (dat$user[i] != dat$user[i-1]) {
                 ct <-c( ct,tail(ct,1)+1)
                 }else{ct <- c(ct, tail(ct,1))} }
> ct
[1] 1 2 2 2 3 4 4 5   # this is your "user_block"

我想我可能不明白你想要什么<代码>数据。表可能是一个开始

#Make data
dat <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Sequen_num = 1:8, 
user = c("A", "C", "C", "C", "A", "C", "C", "A"), time_shift = c(1L, 
15L, 32L, 47L, 65L, 80L, 110L, 120L)), .Names = c("ID", "Sequen_num", 
"user", "time_shift"), class = "data.frame", row.names = c(NA,-8L))

#Calculate running count of A's (or non-C's)
require("data.table")
dat<- data.table(dat)

#Find running cnt of non-C values
dat[,Running.A.Cnt := factor(cumsum(dat$user!="C"))]

#Create a new group variable
dat[user=="C",NewGroup:=.GRP,by=c("user","Running.A.Cnt")]
dat[user!="C",NewGroup:=NA]

#Calculate difference between first and last entry
dat[user=="C",differ:=(time_shift[.N]-time_shift[1]),by=c("NewGroup")]
dat

#     ID Sequen_num user time_shift Running.A.Cnt NewGroup differ
# 1:  1          1    A          1             1       NA     NA
# 2:  1          2    C         15             1        1     32
# 3:  1          3    C         32             1        1     32
# 4:  1          4    C         47             1        1     32
# 5:  1          5    A         65             2       NA     NA
# 6:  1          6    C         80             2        2     30
# 7:  1          7    C        110             2        2     30
# 8:  1          8    A        120             3       NA     NA
#生成数据

dat将表格行缩进4行,谢谢。很长一段时间以来,我一直在使用Stackexchange和overflow进行引用,但从未发布过。我已经搜索了一整天,没有找到任何关于这个问题的具体内容。我已经习惯了像“C-C-C”的每个集群都有一个唯一的ID这样的事情,这将使这变得超级简单。这是一个开始,但它不会让我在索引中为每个CCC组获得不同的值,con2非常感谢。伙计,你知道你的本事。到目前为止,这似乎工作得非常好。哇!我真的需要把R作为一个整体来学习。到目前为止,来自SAS的我正在学习分段,所以现在对我来说非常困难。我注意到的唯一一件事是,最后一个用户块的尾部与下一个用户块的头部的值相同,但我要处理的是,我正在使用cbind将Ct连接到dat,这是一种糟糕的形式吗?它似乎有效,但我可能不完全理解所有的注意事项
cbind
?应该没问题。我最后用这个来打破它,Id:ct 2东西:这只在6万行上运行非常慢,所以在4千万行上它是不可行的。其次,它随机停止工作,现在我得到错误。嘿Mike BondedDust差不多已经搞定了但当进入下一个ID时,它会将最后一次计数带入新ID的第一个实例,所以非常接近。我还需要再玩一玩。嘿,迈克,谢谢,我下一步要试试。嵌套循环实际上需要很长时间才能运行,我非常确信数据表方法会快得多。非常感谢。对不起,我没说清楚,没问题。让我知道运行需要多长时间(以及数据有多大)!每日文件为400K-500K行。所以每个月和每个季度都会有很大的增长。嘿,迈克,这会立即运行,效果很好。而且速度非常快。非常感谢你。我现在决定花一些时间学习R中的数据表包。非常感谢。唯一的问题是,它遇到了与上一个相同的问题,下一个用户ID的第一个C(客户机)块的时间偏移错误,而嵌套的for循环,它将从上一个客户机块(假设773是时间偏移)获取差异,然后从下一个客户机块获取1,得到一个-722的时间偏移,而不是它应该是什么
dput(dat)
structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Sequen_num = 1:8, 
    user = c("A", "C", "C", "C", "A", "C", "C", "A"), time_shift = c(1L, 
    15L, 32L, 47L, 65L, 80L, 110L, 120L)), .Names = c("ID", "Sequen_num", 
"user", "time_shift"), class = "data.frame", row.names = c(NA, 
-8L))

> dat$differ <- ave(dat$time_shift, factor(ct), FUN=function(x) tail(x,1)-head(x,1) )
> dat
  ID Sequen_num user time_shift differ
1  1          1    A          1      0
2  1          2    C         15     32
3  1          3    C         32     32
4  1          4    C         47     32
5  1          5    A         65      0
6  1          6    C         80     30
7  1          7    C        110     30
8  1          8    A        120      0
>  dat$cumtime <- ave(dat$time_shift, factor(ct), FUN=cumsum )
> dat
  ID Sequen_num user time_shift differ cumtime
1  1          1    A          1      0       1
2  1          2    C         15     32      15
3  1          3    C         32     32      47
4  1          4    C         47     32      94
5  1          5    A         65      0      65
6  1          6    C         80     30      80
7  1          7    C        110     30     190
8  1          8    A        120      0     120
runcatf <- function(x) cumsum(c(TRUE, x[-length(x)] != x[-1]))
dat$runcat <- ave (dat$tuser, dat$ID,   FUN=runcatf )
dat.tbl[ , runcat := ave(user) , by=c("ID") ]
#Make data
dat <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Sequen_num = 1:8, 
user = c("A", "C", "C", "C", "A", "C", "C", "A"), time_shift = c(1L, 
15L, 32L, 47L, 65L, 80L, 110L, 120L)), .Names = c("ID", "Sequen_num", 
"user", "time_shift"), class = "data.frame", row.names = c(NA,-8L))

#Calculate running count of A's (or non-C's)
require("data.table")
dat<- data.table(dat)

#Find running cnt of non-C values
dat[,Running.A.Cnt := factor(cumsum(dat$user!="C"))]

#Create a new group variable
dat[user=="C",NewGroup:=.GRP,by=c("user","Running.A.Cnt")]
dat[user!="C",NewGroup:=NA]

#Calculate difference between first and last entry
dat[user=="C",differ:=(time_shift[.N]-time_shift[1]),by=c("NewGroup")]
dat

#     ID Sequen_num user time_shift Running.A.Cnt NewGroup differ
# 1:  1          1    A          1             1       NA     NA
# 2:  1          2    C         15             1        1     32
# 3:  1          3    C         32             1        1     32
# 4:  1          4    C         47             1        1     32
# 5:  1          5    A         65             2       NA     NA
# 6:  1          6    C         80             2        2     30
# 7:  1          7    C        110             2        2     30
# 8:  1          8    A        120             3       NA     NA