Dlaczego zmiana nazwy kolumny zajmuje bardzo dużo czasu przy dużych danych.rama?

Mam data.frame W R z 19 milionami wierszy i 90 kolumnami. Mam mnóstwo zapasowych cykli pamięci RAM i procesora. Wydaje się, że zmiana nazwy pojedynczej kolumny w tej ramce danych jest bardzo intensywną operacją dla R.

system.time(colnames(my.df)[1] <- "foo")
   user  system elapsed 
 356.88   16.54  373.39 
Dlaczego tak jest? Czy każdy wiersz przechowuje jakoś nazwę kolumny? Czy tworzy to zupełnie nową ramkę danych? Wygląda na to, że ta operacja powinna zakończyć się w znikomym czasie. Nie widzę nic oczywistego w R manual entry .

Uruchamiam build 7600 z R (64bit) w systemie Windows 7, a w moim bieżącym obszarze roboczym, ustawianie nazw colnames na małych danych.ramka zajmuje czas " 0 " zgodnie z system.time().

Edit: jestem świadomy możliwości użycia data.table, i szczerze mówiąc, mogę poczekać 5 minut na zakończenie zmiany nazwy, podczas gdy pójdę po herbatę. Interesuje mnie to, co się dzieje i dlaczego?

Author: Matt Dowle, 2012-06-14

1 answers

Jak wspomniało kilku komentatorów, zmiana nazwy kolumn ramki danych jest powolna, ponieważ (w zależności od tego, jak to zrobisz) tworzy od 1 do 4 kopii całych danych.frame . Tutaj, z data.table strony pomocy ?setkey, jest najładniejszy sposób na wykazanie tego zachowania, jaki widziałem:

DF = data.frame(a=1:2,b=3:4)       # base data.frame to demo copies
try(tracemem(DF))                  # try() for non-Windows where R is 
                                   # faster without memory profiling
colnames(DF)[1] <- "A"             # 4 copies of entire object
names(DF)[1] <- "A"                # 3 copies of entire object
names(DF) <- c("A", "b")           # 1 copy of entire object
`names<-`(DF,c("A","b"))           # 1 copy of entire object
x=`names<-`(DF,c("A","b"))         # still 1 copy (so not print method)
# What if DF is large, say 10GB in RAM. Copy 10GB just to change a column name?

Aby (zacząć) rozumieć dlaczego rzeczy są robione w ten sposób, prawdopodobnie będziesz musiał zagłębić się w niektóre z powiązanych dyskusji na temat r-devel. Oto kilka: R-devel: perception and R-devel: Confused about NAMES

Moje impresjonistyczne czytanie tych wątków jest takie, że:

  1. Co najmniej jedna kopia jest wykonana tak, że modyfikacje mogą być "wypróbowane" przed nadpisaniem oryginału. Tak więc, jeśli coś jest nie tak z wartością do ponownego przypisania, [<-.data.frame lub names<- mogą "wycofać się" i dostarczyć komunikat o błędzie bez szkody dla oryginalnego obiektu.

  2. Kilku członków R-core nie całkowicie zadowolony z tego, jak rzeczy działają teraz. Niektórzy ludzie wyjaśniają, że w niektórych przypadkach "R traci utwór"; Luke Tierney wskazuje, że próbował pewnych modyfikacji związanych z tym kopiowaniem w przeszłości "w kilku przypadkach i zawsze musiał się wycofać" ; a Simon Urbanek sugeruje, że "mogą też pojawić się pewne rzeczy"[10]} {25]}

(Jak już powiedziałem, to po prostu impresjonistyczne: po prostu nie jestem w stanie śledzić pełnej rozmowy o szczegółach R wewnętrzne!)


Również istotne, jeśli tego nie widziałeś, oto jak działa coś takiego jak names(z)[3] <- "c2" "naprawdę":

# From ?names<-
z <- "names<-"(z, "[<-"(names(z), 3, "c2"))

Uwaga: Większość tej odpowiedzi pochodzi z odpowiedzi Matthew Dowle ' a na to drugie pytanie . (Pomyślałem, że warto umieścić go tutaj, i dać mu trochę więcej ekspozycji, ponieważ jest tak istotne dla własnego pytania).

 21
Author: Josh O'Brien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:27