2016-03-27 12 views
1

私が記述したインデックス作成の問題hereは、devel data.tableバージョン1.9.7で解決されています。data.table jで関数が呼び出され、予期しない結果が返される

私の質問は、自分の機能にデータを送信したり、自分の機能から戻ったりすることに間違ったことを理解することです。

他の質問に記載されているように、私はgvkeyごとに最も長い連続セグメントのみを保持したいと思います。複数の等しい長さのセグメントがある場合は、最新のものを取ってください。私は基本的に自分自身の機能と同じプロセスをしようとすると

DT[,   step.idx := 0] # initialize 
DT[gap >=2 , step.idx := 1] # 1's at each multi-year jump 
DT[, step.idx := cumsum(step.idx), by = gvkey] # indexes each sequence by firm 
DT[ , seq.lengths := .N, by=.(gvkey,step.idx)]  # length of each sequence 
DT[, keep.seq := 1*(seq.lengths == max(seq.lengths)), by = gvkey]  # each firm's longest sequence 
DT[keep.seq==1, keep.seq := c(rep(0, (.N-max(seq.lengths))), rep(1, max(seq.lengths))), by = gvkey] 

#' expected results: 
DT.out <- DT[keep.seq==1] # 23 
DT.out[keep.seq==0, .N] # 0 
nrow(DT.out)# [1] 149 

私は余分なkeep.seq==0例を得る:

DT[, fyear.lag := shift(fyear, n=1L, type = "lag"), by = gvkey] 
DT[, gap := fyear - fyear.lag] 

は、ここで私は(data.table v1.9.7での)期待される結果が得られます。 私の質問は、私はこのから上記と同じ結果を得ることはありません理由:行の

find.seq.keep <- function(g){ 
    step.idx = rep(0, length(g)) 
    step.idx[g>=2] = 1 
    step.idx = cumsum(step.idx) 
    N.seq = length(unique(step.idx)) 

    seq.lengths = as.vector(unlist(tapply(step.idx, step.idx, 
        function(x) rep(length(x), length(x))))) 
    keep.seq = 1*(seq.lengths == max(seq.lengths)) 
    if(length(keep.seq[keep.seq == 1]) > max(seq.lengths)){ 
     N.max = max(seq.lengths) 
     N.1s = length(keep.seq[keep.seq==1]) 
     keep.seq[keep.seq==1] = c(rep(0, (N.1s-N.max)), rep(1, N.max)) 
    } 
return(as.list(keep.seq)) 
} 
DT[,keep.seqF := find.seq.keep(gap), by = gvkey] 

除去は動作しますが、削除するかのいくつかの偽陽性がある

DT.outF <- DT[keep.seqF==1] 
    DT.outF[keep.seqF==0, .N] # 0 
    nrow(DT.outF) # 141 (<149 = nrow(DT.out) !!) 

は、自分の個人的な機能を働かせて、少なくとも1.9.7がCRANになるまでバージョン1.9.6を使用できるようにしたい(同僚との共有がより簡単になるようにする)。フランクが私の問題を解決する方法を提供したので、find.seq.keepに電話すると、j引数で何が起こっているのかをより把握したいと考えています。

=======

**再現性の例のデータ***

DT <- data.table(
    gvkey = c(1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681, 
       1681, 1681, 1681, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 1914, 
       1914, 1914, 1914, 1914, 1914, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 
       2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 
       2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 
       2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 
       2011, 2011, 2011, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 
       2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 
       2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 
       2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 
       2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2085, 2164, 2164, 2164, 2164, 
       2164, 2164, 2164, 2164, 2164, 2164, 2164, 2164, 2185, 2185, 2185, 2185, 2185, 
       2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 2185, 
       2185, 2185, 2185), 
    fyear = c(1983, 1984, 1985, 1986, 1987, 1988, 1989, 1997, 1998, 2008, 2009, 2010, 2011, 
      2012, 2013, 2014, 1983, 1984, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 
      2001, 2002, 2003, 2004, 2005, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 
      1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 
      1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 
      1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2007, 2008, 
      2009, 2010, 2011, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 
      1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 
      1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 
      1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 
      2000, 2001, 2002, 2003, 2004, 2005, 2006, 2011, 2012, 1978, 1979, 1980, 1981, 
      1982, 1983, 1984, 1985, 1986, 1989, 1990, 1991, 1970, 1971, 1972, 1973, 1974, 
      1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 
      1988, 1994, 1995)) 

setkey(DT, gvkey, fyear) 
+1

あなたが問題を狭くすることで、ポストを短くしていただけますか?私は – Arun

+0

私はそれを短縮しました。 –

+2

あなたのQは、ベースR、IIUCで書いた関数をデバッグしようとしています。そして、 'seq.lengths'を作成している場所で、' gvkey、step 'を使用する可能性が最も高いです。idx'グループ、そしてtapplyの 'step.idx'だけです。あなたの関数で 'debugonce()'を使い、出力をチェックしながら行ごとに再実行してください。 – Arun

答えて

3

あなたの機能が動作しない理由を私はわからないんだけど、ここでは別のアプローチです:

DT[, g := cumsum(fyear - shift(fyear, fill=fyear[1L]-1L) != 1L), by=gvkey] 
keep = DT[, 
    .(len = .N), by=.(gvkey, g)][, 
    .(g = g[tail(which(len == max(len)), 1)]), by=gvkey] 

DT.out = DT[keep, on=names(keep)] 

DT.out[, .N] # 149, as expected 

は、それがどのように動作:

  • gは、それぞれgvkey内の実行IDです。
  • lenは、各実行の長さです。
  • g[tail(which(len == max(len)), 1)]は、最新のものを使用して最長の、結びつきのつながりです。
  • DT[keep, on=names(keep)は、keepで見つかったDTから(gvkey,g)の部分集合です。何らかの理由で、あなたがこれを行うには基本機能を望んでいた、場合

...

tag.long.seq = function(x){ 
    g = cumsum(c(1L, diff(x) > 1L)) 
    len = tapply(g, g, FUN = length) 
    w = tail(which(len == max(len)), 1L) 

    ave(g, g, FUN = function(z) z[1] == w)  
} 

DT[, keepem := tag.long.seq(fyear), by=gvkey] 

DT[(keepem==1L), .N] # 149 again 
+0

ありがとう!非常に洗練された解決策のようですが、私は 'keep'の2行目にエラーが表示されます: 'by'または 'keyby'リストの項目は長さ(172,16)です。それぞれは、xの行やi(172)が返す行の長さと同じ長さでなければなりません。 '...また、' cumsum'で '!= 1L'とは何ですか? –

+1

@TonyBeans Hm、なぜあなたはそのエラーを叩いているのか分かりません。 '!= 1'は論理テストです。ギャップが1でなければTRUE、そうでなければFALSEです。結果に 'cumsum'が適用されると、これらはそれぞれ1/0にマッピングされます。 – Frank

+1

申し訳ありませんが、私が試したときにタイプミスがありました。これは 'data.table'の両方のバージョンで完全に動作します。私は「尾」にもかかわらず、とても素敵でした。ありがとうございました。 (そして今、私は 'cumsum'、thnxで何が起こっているのか見ています)。これが究極の問題を解決したとしても、私の質問は「j」を理解するより一般的な問題であったので、答えとして受け止めておくべきだと思います。それにもかかわらず、非常に感謝! –

関連する問題