2010-04-11 19 views
5

Mam ramkę danych w R i chciałbym wykonać obliczenia na wszystkich parach wierszy. Czy jest prostszy sposób, aby to zrobić niż za pomocą zagnieżdżonej pętli for?Operate na parach wierszy ramki danych

Aby to zrobić, należy rozważyć ramkę danych z dziesięcioma rzędami i chcę obliczyć różnicę wyników między wszystkimi (45) możliwymi parami.

> data.frame(ID=1:10,Score=4*10:1) 
    ID Score 
1 1 40 
2 2 36 
3 3 32 
4 4 28 
5 5 24 
6 6 20 
7 7 16 
8 8 12 
9 9  8 
10 10  4 

Wiem, że mógłbym robić tego obliczenia z zagnieżdżonej pętli for, ale jest tam lepsze (bardziej R-owski) sposób to zrobić?

Odpowiedz

4

Oto inne rozwiązanie używając combn:

df <- data.frame(ID=1:10,Score=4*10:1) 
cm <- combn(df$ID,2) 
delta <- df$Score[cm[1,]]-df$Score[cm[2,]] 

lub bardziej bezpośrednio

df <- data.frame(ID=1:10,Score=4*10:1) 
delta <- combn(df$ID,2,function(x) df$Score[x[1]]-df$Score[x[2]]) 
+0

Ooh, bardzo lubię funkcję combn. –

+0

+1 Myślę, że może to być funkcja często pomijana. – Iterator

+0

Próbuję replikować to na ramce danych z kilkoma kolumnami, ale nie mogę sprawić, aby działało. Może @teucer może pokazać, jak to zrobić? Na przykład. jeżeli był score1, score2, score3 itd. Dla jasności różnica między [1,2] a [2,2], a nie sumą [1,] i sumą [2,]. W efekcie otrzymasz ramkę danych z taką samą liczbą kolumn, co oryginalna, ale z większą liczbą wierszy. –

7

celu obliczenia różnic, być może można użyć

outer(df$Score,df$Score,"-") 
3
colmx = matrix(rep(df[,2], 10), ncol=10, byrow=F) 
rowmx = matrix(rep(df[,2], 10), ncol=10, byrow=T) 
delta = colmx - rowmx 
+0

~ ubuntu i dostaję tę samą odpowiedź; "zewnętrzna" jest opakowaniem po obliczeniach macierzy, które zrobiłem jawnie, co tłumaczy różnicę wydajności między tymi dwoma - dla matrycy 100 x 100, uśrednionej na ponad 100 próbach, wbudowanie było tylko o 10% wolniejsze - biorąc pod uwagę wszystkie artefakty przy mierzeniu tego rodzaju rzeczy, powiedziałbym, że to w granicach progu hałasu. – doug

3

dist() jest ty r przyjacielu.

dist(df$Score) 

Można umieścić go jako matrycy:

as.matrix(dist(df$Score)) 
+0

Jak mi brakowało (innego) wbudowanego ?! W każdym razie miły, +1 ode mnie. – doug

Powiązane problemy