このエラーを回避する方法は知っていますが、この方法で実行するとなぜこのエラーが発生するのかわかりません。
datain <- data.frame(
chrom = c("chr17", "chr4", "chr5", "chr13"),
map = c(81061047, 106061533, 40102442, 73791553),
rs = c("rs75954926", "rs7679673", "rs7708610", "rs78341008"),
start = c(79061048, 104061534, 38102443, 71791554),
end = c(83061048, 108061534, 42102443, 75791554)
)
datain
datain$chr<-datain$chrom
setDT(datain)
setkey(datain, chr, start, end)
datain
ありがとう!
アレックス
これは、Windows10とmacOS10.13.6の両方でdata.table1.12.0を使用して再現できます。 macOSシステムをdata.table1.12.2にアップグレードした後、以下のすべての例で同じ結果が得られることを確認できます。
やや単純な例:
> set.seed(1)
> d <- data.frame(x = paste0("chr",sample(17)[3:6]), y = 1:4)
> d$x2 <- d$x
> d
x y x2
1 chr9 1 chr9
2 chr13 2 chr13
3 chr3 3 chr3
4 chr11 4 chr11
> setDT(d)
> setkey(d,x2,y)
> d
x y x2
1: chr9 4 chr9
2: chr13 2 chr13
3: chr3 3 chr3
4: chr11 1 chr11
これは、キーをsetDT
直接割り当てた場合にも発生します(これは、 setDT
がsetkeyv
を使用してキーを設定するためです)。
> set.seed(1)
> d <- data.frame(x = paste0("chr",sample(17)[3:6]), y = 1:4)
> d$x2 <- d$x
> d
x y x2
1 chr9 1 chr9
2 chr13 2 chr13
3 chr3 3 chr3
4 chr11 4 chr11
> setDT(d, key = c("x2","y"))
> d
x y x2
1: chr9 4 chr9
2: chr13 2 chr13
3: chr3 3 chr3
4: chr11 1 chr11
ご覧のとおり、 y
列の順序は変更されていますが、他の列の順序は変更されていません。 どうやらこれは、data.frameの方法で列をコピーし、 setDT
を使用してから、 setkey
使用した場合にのみ発生します。 次の5つのケースを考えてみましょう。これらはすべて、意図した結果をもたらします。
1)データフレーム列をコピーしない
> set.seed(1)
> d <- data.frame(x = paste0("chr",sample(17)[3:6]), y = 1:4)
> d
x y
1 chr9 1
2 chr13 2
3 chr3 3
4 chr11 4
> setDT(d)
> setkey(d,x)
> d
x y
1: chr11 4
2: chr13 2
3: chr3 3
4: chr9 1
2)データフレームに任意の新しい列を作成する
> set.seed(1)
> d <- data.frame(x = paste0("chr",sample(17)[3:6]), y = 1:4)
> set.seed(1)
> d$x2 <- paste0("chr",sample(17)[1:4])
> d
x y x2
1 chr9 1 chr5
2 chr13 2 chr6
3 chr3 3 chr9
4 chr11 4 chr13
> setDT(d)
> setkey(d,x2,y)
> d
x y x2
1: chr11 4 chr13
2: chr9 1 chr5
3: chr13 2 chr6
4: chr3 3 chr9
3)既存の列をサンプリングし、いくつかの外部文字をその列に貼り付けて、新しい列を作成します
> set.seed(1)
> d <- data.frame(x = paste0("chr",sample(17)[3:6]), y = 1:4)
> set.seed(1)
> d$x2 <- paste0("new_",sample(d$x,4))
> d
x y x2
1 chr9 1 new_chr13
2 chr13 2 new_chr11
3 chr3 3 new_chr3
4 chr11 4 new_chr9
> setDT(d)
> setkey(d,x2,y)
> d
x y x2
1: chr13 2 new_chr11
2: chr9 1 new_chr13
3: chr3 3 new_chr3
4: chr11 4 new_chr9
4)既存のカラムをサンプリングするだけで新しいカラムを作成する
> set.seed(1)
> d <- data.frame(x = paste0("chr",sample(17)[3:6]), y = 1:4)
> set.seed(1)
> d$x2 <- sample(d$x,4)
> d
x y x2
1 chr9 1 chr13
2 chr13 2 chr11
3 chr3 3 chr3
4 chr11 4 chr9
> setDT(d)
> setkey(d,x2,y)
> d
x y x2
1: chr13 2 chr11
2: chr9 1 chr13
3: chr3 3 chr3
4: chr11 4 chr9
5)列をdata.tableの方法でコピーする
> set.seed(1)
> d <- data.frame(x = paste0("chr",sample(17)[3:6]), y = 1:4)
> d
x y
1 chr9 1
2 chr13 2
3 chr3 3
4 chr11 4
> setDT(d)
> d[, x2 := x][]
x y x2
1: chr9 1 chr9
2: chr13 2 chr13
3: chr3 3 chr3
4: chr11 4 chr11
> setkey(d,x2,y)
> d
x y x2
1: chr11 4 chr11
2: chr13 2 chr13
3: chr3 3 chr3
4: chr9 1 chr9
このバグは(非常に)特定のユースケースで発生するようですが、私はいくつかの本番システムでsetkey
を使用しているため、これは私にとって重大な場合があります。 この特定のケースが私の製品コードで発生するかどうかを確認します。
@jaapwalhoutの観察結果を確認し
また、(i)要因に関連している可能性があると考えましたが、そうではありません(文字または整数でも発生します)、(ii)キー(xまたはy)に関係なく発生します。
以下に、より単純な再現可能な例を示します。
課題の警告は関連しているかもしれませんが、私にはわかりません。
options(datatable.verbose = TRUE)
## KO
d <- data.frame(x = c(9, 1), y = c(9, 1))
d$x2 <- d$x
d
# x y x2
# 1 9 9 9
# 2 1 1 1
setDT(d, key = "x")[]
# forder took 0 sec
# reorder took 0 sec
# x y x2
# 1: 9 1 9
# 2: 1 9 1
## KO
d <- data.frame(x = c("9", "1"), y = c(9, 1), stringsAsFactors = FALSE)
d$x2 <- d$x
d
# x y x2
# 1 9 9 9
# 2 1 1 1
setDT(d, key = "x")[]
# forder took 0 sec
# reorder took 0 sec
# x y x2
# 1: 9 1 9
# 2: 1 9 1
## OK (with warning)
d <- data.frame(x = c("9", "1"), y = c(9, 1))
setDT(d)
d$x2 <- d$x
# Assigning to all 2 rows
# RHS for item 1 has been duplicated because NAMED is 2, but then is being plonked. length(values)==2; length(cols)==1)
setkey(d, y, verbose = TRUE)[]
# forder took 0 sec
# reorder took 0 sec
# x y x2
# 1: 1 1 1
# 2: 9 9 9
iiuc、変更せずに列またはリスト要素を複製する場合、メモリアドレスは同じになり、キーを設定すると「混乱」します。
copy()
ます。
# KO
l <- list(x = c(9, 1), y = c(9, 1))
l[["z"]] <- l[["x"]]
l
setDT(l, key = "x")[]
address(l$x) == address(l$z)
# TRUE
# OK
l <- list(x = c(9, 1), y = c(9, 1))
l[["z"]] <- copy(l[["x"]])
l
setDT(l, key = "x")[]
最も参考になるコメント
iiuc、変更せずに列またはリスト要素を複製する場合、メモリアドレスは同じになり、キーを設定すると「混乱」します。
copy()
ます。