2013-02-08 22 views
5

Mam ramkę danych z trzema kolumnami: ref, cel, odległość. Każdy ref ma zmierzoną odległość do tego samego zestawu celów i chciałbym uzyskać wektor minimalnych odległości dla każdego ref. Teraz robię to z pętlą for, ale wygląda na to, że powinien istnieć sposób na wektoryzację tego.Wektoryzacja dla pętli nad ramką danych w R

Oto mój kod:

refs <- levels(data$ref) 

result <- c() 
for (ref in refs) { 
    # Find the minimum distance for observations with the current ref 
    # but be sure to protect against ref == target! 
    best_dist <- min(data[data$ref == ref & data$target != ref,]$distance) 
    result <- c(result, best_dist) 
} 

Am I skazane przez posiadające moja ramka danych skonfigurowana w ten sposób, czy też istnieje dobry sposób na wektorować to? Dzięki za pomoc!

Odpowiedz

6

Nigdy nie powiększaj obiektu w pętli, używając c, cbind, rbind. Obiekt będzie kopiowany za każdym razem. Zamiast tego należy wstępnie przydzielić do prawidłowego rozmiaru (lub niektóre przeszacować, jeśli wynik jest płynny).

Mimo to, pętla nie wymaga tutaj

I jak data.table s na wydajność pamięci i kodowania elegancji.

library(data.table) 
DT <- data.table(data) 


DT[ref != target, list(bestdist = min(distance)), by = ref] 

jeśli ref i cel są kolumny czynnikiem różnych poziomach (jak zasugerowano w komentarzu), a następnie albo uczynić je mieć identyczne poziomy lub przekonwertować na postać

DT[as.character(ref) != as.character(target), list(bestdist = min(distance)), by = ref] 
+0

myślę, że masz a ')' brakuje tam ... – adibender

+0

ta. Naprawiono teraz .. – mnel

+0

To wydaje się nie działać całkiem dobrze, jak jest. Otrzymuję następujący błąd podczas próby: ** Błąd w Ops.factor (ref, target): różne zestawy współczynników są różne ** Jednak ** DT [, lista (bestdist = min (odległość)), przez = ref] ** Powoduje wyjście, ale bez wartości ref = kontrola celu. – weitzner