Data.table: Fehler bei Verwendung der Funktion setkey

Erstellt am 9. Apr. 2019  ·  3Kommentare  ·  Quelle: Rdatatable/data.table

Ich weiß, wie ich diesen Fehler vermeiden kann, aber ich weiß nicht, warum dieser Fehler auftritt, wenn ich ihn auf diese Weise ausführe.

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

Vielen Dank!

Alex

bug

Hilfreichster Kommentar

iiuc, wenn eine Spalte oder ein Listenelement ohne Änderung dupliziert wird, ist die Speicheradresse dieselbe und das Einstellen des Schlüssels "bringt die Dinge durcheinander".
Funktioniert einwandfrei, wenn 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")[]

Alle 3 Kommentare

Ich kann dies mit data.table 1.12.0 unter Windows 10 und macOS 10.13.6 reproduzieren. Nach dem Upgrade meines macOS-Systems auf data.table 1.12.2 kann ich bestätigen, dass alle folgenden Beispiele das gleiche Ergebnis liefern.

Ein etwas einfacheres Beispiel:

> 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

Dies geschieht auch, wenn Sie den Schlüssel direkt mit setDT zuweisen (was zu erwarten ist, da setDT setkeyv , um die Schlüssel festzulegen):

> 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

Wie Sie sehen können, wird die Reihenfolge der y -Spalte geändert, während die Reihenfolge der anderen Spalten nicht geändert wird. Anscheinend geschieht dies nur, wenn Sie eine Spalte auf die Weise von data.frame kopieren, dann setDT und dann setkey . Betrachten Sie die folgenden fünf Fälle, die alle das beabsichtigte Ergebnis liefern:

1) Kopieren einer Datenrahmenspalte nicht

> 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) Erstellen einer beliebigen neuen Spalte im Datenrahmen

> 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) Erstellen einer neuen Spalte durch Abtasten einer vorhandenen Spalte und Einfügen einiger externer Zeichen

> 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) Erstellen einer neuen Spalte durch einfaches Abtasten einer vorhandenen Spalte

> 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) Kopieren einer Spalte auf die Weise 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

Obwohl dieser Fehler in einem (sehr) spezifischen Anwendungsfall auftritt, kann dies für mich kritisch sein, da ich in mehreren Produktionssystemen setkey verwende. Überprüft, ob dieser spezielle Fall in meinem Produktionscode auftritt.

Bestätigen @jaapwalhout ‚s Beobachtungen (mit data.table_1.12.3).
Auch (i) dachte, es könnte mit Faktoren zusammenhängen, aber es ist nicht (passiert auch mit Zeichen oder Ganzzahlen), (ii) es passiert unabhängig von der Taste (x oder y).
Unten ein einfacheres reproduzierbares Beispiel.
Die Warnung in der Aufgabe kann verwandt sein, aber ich bin nicht sicher, ob ich sie verstehe.

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, wenn eine Spalte oder ein Listenelement ohne Änderung dupliziert wird, ist die Speicheradresse dieselbe und das Einstellen des Schlüssels "bringt die Dinge durcheinander".
Funktioniert einwandfrei, wenn 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")[]
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen