Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 使用data.table标识从0到1的跳转_R_Data.table - Fatal编程技术网

R 使用data.table标识从0到1的跳转

R 使用data.table标识从0到1的跳转,r,data.table,R,Data.table,我有下面的data.table和感兴趣的变量x。我想创建另一个变量,它指示x从0跳到1,这意味着该变量在某一年之前一直为0,之后的所有年份都为1。这应该由id\u d完成 有没有一种简单的data.table方法可以做到这一点 原始数据表: fullDat <- data.table(id_d = rep(letters[1:3], each=12), year=rep(1:12, 3), x = c(rep(0

我有下面的data.table和感兴趣的变量
x
。我想创建另一个变量,它指示
x
从0跳到1,这意味着该变量在某一年之前一直为0,之后的所有年份都为1。这应该由
id\u d
完成

有没有一种简单的data.table方法可以做到这一点

原始数据表:

 fullDat <- data.table(id_d = rep(letters[1:3], each=12), 
                  year=rep(1:12, 3), 
                  x = c(rep(0, 5), rep(1, 7), 0,1,0,1,2,2,4, rep(5,5), 1, rep(0, 3), rep(1, 8)))

    id_d year x
  1:    a    1 0
  2:    a    2 0
  3:    a    3 0
  4:    a    4 0
  5:    a    5 0
  6:    a    6 1
  7:    a    7 1
  8:    a    8 1
  9:    a    9 1
 10:    a   10 1
 11:    a   11 1
 12:    a   12 1
 13:    b    1 0
 14:    b    2 1
 15:    b    3 0
 16:    b    4 1
 17:    b    5 2
 18:    b    6 2
 19:    b    7 4
 20:    b    8 5
 21:    b    9 5
 22:    b   10 5
 23:    b   11 5
 24:    b   12 5
 25:    c    1 1
 26:    c    2 0
 27:    c    3 0
 28:    c    4 0
 29:    c    5 1
 30:    c    6 1
 31:    c    7 1
 32:    c    8 1
 33:    c    9 1
 34:    c   10 1
 35:    c   11 1
 36:    c   12 1
id_d year x
我们能做到

fullDat[, jump := {i1 <- which.max(x)
       if(all(x[i1:.N]==1)) replace(rep(0, .N), i1, 1) else 0}, 
           id_d]
fullDat
#    id_d year x jump
# 1:    a    1 0    0
# 2:    a    2 0    0
# 3:    a    3 0    0
# 4:    a    4 0    0
# 5:    a    5 0    0
# 6:    a    6 1    1
# 7:    a    7 1    0
# 8:    a    8 1    0
# 9:    a    9 1    0
#10:    a   10 1    0
#11:    a   11 1    0
#12:    a   12 1    0
#13:    b    1 0    0
#14:    b    2 1    0
#15:    b    3 0    0
#16:    b    4 1    0
#17:    b    5 2    0
#18:    b    6 2    0
#19:    b    7 4    0
#20:    b    8 5    0
#21:    b    9 5    0
#22:    b   10 5    0
#23:    b   11 5    0
#24:    b   12 5    0
#25:    c    1 1    0
#26:    c    2 0    0
#27:    c    3 0    0
#28:    c    4 0    0
#29:    c    5 1    0
#30:    c    6 1    0
#31:    c    7 1    0
#32:    c    8 1    0
#33:    c    9 1    0
#34:    c   10 1    0
#35:    c   11 1    0
#36:    c   12 1    0
该变量在某一年之前为0,在随后的所有年份中为1

不需要制作中间表
wDT
;将它的完整代码写入最终声明也可以。事实上,如果需要的话,它可以在一行中,比如

DT[, x := 0L][code_for_wDT, on=on_cols, x := 1L]

或者,使用
.I
中的行号代替联接:

# find rows to assign one
w = fullDat[, with(rle(x), .I[
  if (identical(values, c(0, 1))) first(lengths) + 1L
  else 0L
]), by=id_d]$V1

# initialize to zero
fullDat[, jump := 0L ]
# update to assign ones
fullDat[w, jump := 1L ]
工作原理:

  • cumsum(x==0)==(1:.N-1L)
    检查直到并包括此行的零数是否等于前面的行数
  • rev(cumsum(rev(x==1)))==.N:1
    检查从最后一行向后(向下到并包括这一行)计数的行数是否等于从这里到末尾的行数

  • 在我看来,太聪明了。例如,它在
    DT=data.table(id_d=rep(“d”,4),year=1:4,x=c(0,1,0,2))
    上出现中断。好的观点@Frank,我添加了额外的逻辑测试来检查0和1值。我现在应该抓住这些案子是的,现在我认为它对所有案子都有效。尽管如此,我仍然觉得它不必要的晦涩难懂。仅供参考,这打破了
    DT=data.table(id_d=rep(“d”,4),year=1:4,x=c(0,1,0,1))
    (实际上对于长版本和“紧凑”版本给出了不同的结果)@Frank我没有测试所有的情况
    # find rows to assign one
    wDT = fullDat[, .(year = year[with(rle(x), 
      if (identical(values, c(0, 1))) first(lengths) + 1L
      else 0L
    )]), by=id_d]
    
    # initialize to zero
    fullDat[, jump := 0L ]
    # update join to assign ones
    fullDat[wDT, on=.(id_d, year), jump := 1L ]
    
    DT[, x := 0L][code_for_wDT, on=on_cols, x := 1L]
    
    # find rows to assign one
    w = fullDat[, with(rle(x), .I[
      if (identical(values, c(0, 1))) first(lengths) + 1L
      else 0L
    ]), by=id_d]$V1
    
    # initialize to zero
    fullDat[, jump := 0L ]
    # update to assign ones
    fullDat[w, jump := 1L ]
    
    fullDat[, jump := (cumsum(x==0)==(1:.N - 1L)) & (rev(cumsum(rev(x==1))) == .N:1), id_d]