Data.table: خطأ في استخدام وظيفة setkey

تم إنشاؤها على ٩ أبريل ٢٠١٩  ·  3تعليقات  ·  مصدر: Rdatatable/data.table

أعرف كيفية تجنب هذا الخطأ ، لكنني لا أعرف سبب حدوث هذا الخطأ إذا قمت بتشغيله بهذه الطريقة.

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

شكرا!

اليكس

bug

التعليق الأكثر فائدة

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")[]

ال 3 كومينتر

يمكنني إعادة إنتاج هذا باستخدام data.table 1.12.0 على كل من Windows 10 و macOS 10.13.6. بعد ترقية نظام macOS الخاص بي إلى data.table 1.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 . ضع في اعتبارك الحالات الخمس التالية التي تعطي جميعها النتيجة المرجوة:

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 الصورة الملاحظات (مع data.table_1.12.3).
أيضًا ، (1) اعتقدت أنه قد يكون مرتبطًا بعوامل ولكنه ليس كذلك (يحدث أيضًا مع حرف أو عدد صحيح) ، (2) يحدث مهما كان المفتاح (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")[]
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات