22

これは、この質問に続いて尋ねるべきだと思ったものです。R-forge トラッカーに報告する前に、これがバグ/不一致であるかどうかを確認したいと思います。

これを考慮してくださいdata.table

require(data.table)
DT <- data.table(x=c(1,0,NA), y=1:3)

ここで、0 ではないDT のすべての行にアクセスするには、次の方法で行うことができます。

DT[x != 0]
#    x y
# 1: 1 1
DT[!(x == 0)]
#     x y
# 1:  1 1
# 2: NA 3

基礎となる論理演算が同等である場合にアクセスするDT[x != 0]と、異なる結果が得られます。DT[!(x==0)]

注:これを data.frame に変換してこれらの操作を実行すると、論理的に同等の両方の操作で互いに同一の結果が得られますが、その結果はこれらの data.table の両方の結果とは異なります。理由の説明については?`[`、セクションの下を参照してNAs in indexingください。

編集:との同等性を強調している人もいるのでdata.frame、data.frame での同じ操作からの出力のスニペットを次に示します。

DF <- as.data.frame(DT)
# check ?`[` under the section `NAs in indexing` as to why this happens
DF[DF$x != 0, ]
#     x  y
# 1   1  1
# NA NA NA
DF[!(DF$x == 0), ]
#     x  y
# 1   1  1
# NA NA NA

これは矛盾していると思いますが、どちらも同じ結果になるはずです。しかし、どの結果ですか?のドキュメントに[.data.tableは次のように書かれています:

i ---> 整数、logical または文字ベクトル、列名の式、list または data.table。

整数ベクトルと論理ベクトルは、[.data.frame. 論理 i の NA 以外は FALSE として扱われ、[.data.frame.

で同じ操作を行った場合と結果が異なる理由は明らかdata.frameです。それでも、data.table 内では、これが当てはまる場合、両方が返されます。

#    x y
# 1: 1 1

[.data.tableソースコードを調べて、なぜこれが起こっているのか理解しましなぜこれが起こっているのかについての詳細な説明については、この投稿を参照 してください。

簡単に言えば、x != 0「論理的」と評価されNA、FALSE に置き換えられます。ただし、!(x==0)は最初(x == 0)に論理的に評価されNA、FALSE に置き換えられます。次に、否定が発生し、NA基本的に になりTRUEます。

それで、私の最初の(またはむしろ主な)質問は、これはバグ/矛盾ですか?もしそうなら、data.table R-forge トラッカーにファイルします。そうでない場合は、この違いの理由を知りたいです。また、この違いを説明するドキュメントの修正を提案したいと思います (すでに素晴らしいドキュメントです!)。

編集:data.tableコメントをフォローアップすると、2 番目の質問はNAdata.frame?? (しかし、@Rolandのコメントに従って、これは意見につながる可能性が非常に高く、この質問にまったく答えなくてもまったく問題ありません)。

4

4 に答える 4

7

文書化されており、一貫した動作だと思います。

注意すべき主なことは、引数!内の接頭辞 は非結合のフラグであるため、 data.table 内の文書化された NA の処理を​​使用する場合、 と は同じ論理演算ではなくなることです。ix != 0!(x==0)

に関するニュースのセクションnot join

A new "!" prefix on i signals 'not-join' (a.k.a. 'not-where'), #1384i.
            DT[-DT["a", which=TRUE, nomatch=0]]   # old not-join idiom, still works
            DT[!"a"]                              # same result, now preferred.
            DT[!J(6),...]                         # !J == not-join
            DT[!2:3,...]                          # ! on all types of i
            DT[colA!=6L | colB!=23L,...]          # multiple vector scanning approach (slow)
            DT[!J(6L,23L)]                        # same result, faster binary search
        '!' has been used rather than '-' :
            * to match the 'not-join'/'not-where' nomenclature
            * with '-', DT[-0] would return DT rather than DT[0] and not be backwards
              compatible. With '!', DT[!0] returns DT both before (since !0 is TRUE in
              base R) and after this new feature.
            * to leave DT[+J...] and DT[-J...] available for future use

そしてから?data.table

すべてのタイプの 'i' には ! をプレフィックスとして付けることができます。これは、not-join または not-select を実行する必要があることを示します。data.table のドキュメント全体で、'i' の型を参照する場合、'!' の後の 'i' の型を意味します (存在する場合)。例を参照してください。


data.table 内の文書化された NA の処理と一致するのはなぜですか

NA値は FALSE と見なされます。isTRUE各要素に対して行うように考えてください。

soは、文書化された NA 処理により、これDT[x!=0]で索引付けされます。TRUE FALSE NATRUE FALSE FALSE

物事がTRUEの場合、サブセット化したいと考えています。

これは、x != 0 が TRUE である (NA ではない) ものを取得していることを意味します。

DT[!(x==0)]0 以外のすべてのもの (値を含めることができます) が必要な結合しない状態を使用しNAます。


フォローアップ クエリ / その他の例

DT[!(x!=0)]

## returns
    x y
1:  0 2
2: NA 3

x!=0は 1 つの値に対して TRUE であるため、not 結合は真でないものを返します。(つまり、FALSE(実際に== 0) だったもの、またはNA

DT[!!(x==0)]

## returns
    x y
1:  0 2
2: NA 3

これは として解析され!(!(x==0))ます。プレフィックス!は結合しないことを示し、内部!(x==0)は と同じように解析されるx!=0ため、すぐ上のケースの推論が適用されます。

于 2013-04-27T06:43:51.590 に答える
4

バージョン 1.8.11 以降!論理式の非結合をトリガーせず、2 つの式の結果は同じです。

DT <- data.table(x=c(1,0,NA), y=1:3)
DT[x != 0]
#   x y
#1: 1 1
DT[!(x == 0)]
#   x y
#1: 1 1

@mnel の回答で言及されている他のいくつかの式も、より予測可能な方法で動作するようになりました。

DT[!(x != 0)]
#   x y
#1: 0 2
DT[!!(x == 0)]
#   x y
#1: 0 2
于 2013-10-15T17:35:45.633 に答える
0

私の見解では、それsubsetは正しいことを行い、その両方data.tableを行ってdata.frameはいないというものdata.frameです。したがって、あなたの質問に関する限り、いいえ、 とdata.table同じことをすべきでdata.frameはないと思いますsubset

記録のために、これがの出力ですsubset

subset(DF, x != 0)
#  x y
#1 1 1
subset(DF, !(x == 0))
#  x y
#1 1 1
#
# or if you want the NA's as well
subset(DF, is.na(x) | x != 0)
#   x y
#1  1 1
#3 NA 3

data.frame出力がばかげている理由について少し詳しく説明したいと思います。[.data.frame説明の最初の行には、「データ フレームのサブセットを抽出または置換する」と書かれています。返される出力には、rowname = の行がありNA、すべての要素が等しい場合NA、指定されたデータ フレームの「サブセット」とは言えず、出力が関数の意味と一致しません。また、これらのことを常に認識し、この動作を回避する方法を見つける必要があるため、ユーザーの観点からも非常に面倒です。

出力に関する限り、data.table明らかに一貫性がありませんが、どちらの場合も実際には元のデータ テーブルのサブセットが返されるという点で、少なくともばかげたことではありません。

于 2013-04-26T15:32:56.903 に答える