2015-04-17 24 views
5

w następującym zbiorze, chciałbym, aby pomnożyć wartość w kolumnie Size przez wartość w kolumnie Month1, Month2 lub Month3 w zależności od tego, co numer mamy w kolumnie Month. Jeśli więc w pewnym wierszu wartość Month wynosi 2, chciałbym pomnożyć wartość w kolumnie Size przez wartość w kolumnie Month2 i zapisać wynik w nowej kolumnie NewSize. Bardzo dziękuję za pomoc z góry!Pomnażanie wartość kolumny przez inną wartość w zależności od wartości określonej w kolumnie R

Orig = c("A","B","A","A","B","A","A","B","A") 
Dest = c("B","A","C","B","A","C","B","A","C") 
Month = c(1,1,1,2,2,2,3,3,3) 
Size = c(30,20,10,10,20,20,30,50,20) 
Month1 = c(1,0.2,0,1,0.2,0,1,0.2,0) 
Month2 = c(0.6,1,0,0.6,1,0,0.6,1,0) 
Month3 = c(0,1,0.6,0,1,0.6,0,1,0.6) 
df <- data.frame(Orig,Dest,Month,Size,Month1,Month2,Month3) 
df 

    Orig Dest Month Size Month1 Month2 Month3 
1 A B  1 30 1.0 0.6 0.0 
2 B A  1 20 0.2 1.0 1.0 
3 A C  1 10 0.0 0.0 0.6 
4 A B  2 10 1.0 0.6 0.0 
5 B A  2 20 0.2 1.0 1.0 
6 A C  2 20 0.0 0.0 0.6 
7 A B  3 30 1.0 0.6 0.0 
8 B A  3 50 0.2 1.0 1.0 
9 A C  3 20 0.0 0.0 0.6 

Odpowiedz

1

Oto jedna alternatywa korzystania ifelse

> transform(df, NewSize=ifelse(Month==1, Size*Month1, 
        ifelse(Month==2, Size*Month2, Size*Month3))) 
    Orig Dest Month Size Month1 Month2 Month3 NewSize 
1 A B  1 30 1.0 0.6 0.0  30 
2 B A  1 20 0.2 1.0 1.0  4 
3 A C  1 10 0.0 0.0 0.6  0 
4 A B  2 10 1.0 0.6 0.0  6 
5 B A  2 20 0.2 1.0 1.0  20 
6 A C  2 20 0.0 0.0 0.6  0 
7 A B  3 30 1.0 0.6 0.0  0 
8 B A  3 50 0.2 1.0 1.0  50 
9 A C  3 20 0.0 0.0 0.6  12 
+1

doskonały, dzięki! – MIH

2

Oto jak ja sobie z tym poradzić stosując data.table.

require(data.table) 
setkey(setDT(df), 
     Month)[.(mon = 1:3),       ## i 
     NewSize := Size * get(paste0("Month", mon)), ## j 
     by=.EACHI]         ## by 
  • setDT przekształca df z data.frame do data.table przez odniesienie.
  • setkey porządkuje że data.table przez kolumny określonej, Month, w kolejności rosnącej i znaków, które kolumna jako kluczowego kolumnie, na której będziemy wykonywać przyłączyć.
  • Wykonujemy sprzężenie na kluczowym zestawie kolumn z poprzedniego zestawu z wartościami 1:3. Można to również interpretować jako operację podzbiór, która wyodrębnia wszystkie wiersze pasujące do 1,2 and 3 z kolumny klucza Month.

  • Tak więc, dla każdej wartości 1:3, obliczamy pasujące wiersze w i. W przypadku pasujących wierszy obliczamy NewSize, wyodrębniając Size i MonthX dla pasujących wierszy i mnożąc je. Używamy get(), aby uzyskać wyodrębnienie właściwej kolumny MonthX.

  • by=.EACHI jak sama nazwa wskazuje, wykonuje wyrażenie w postaci j dla każdego i. Jako przykład, i=1 dopasowuje (lub dołącza) do wierszy 1: 3 z df. W przypadku tych wierszy wyrażenie j wyodrębnia wartości Size = 30,20,10 i Month1 = 1.0, 0.2, 0.0, a następnie zwraca wartość 30, 4, 0. A następnie za i=2 i tak dalej ..

nadzieję, że to pomaga trochę nawet jeśli szukasz dplyr tylko odpowiedzieć.

+0

wielkie dzięki, że bardzo pomaga. musisz się nauczyć "data.table" – MIH

1

Można użyć apply:

apply(df, 1, function(u) as.numeric(u[paste0('Month', u['Month'])])*as.numeric(u['Size'])) 
#[1] 30 4 0 6 20 0 0 50 12 

lub vectorized rozwiązanie:

bool = matrix(rep(df$Month, each=3)==rep(1:3, nrow(df)), byrow=T, ncol=3) 

df[c('Month1', 'Month2', 'Month3')][bool] * df$Size 
#[1] 30 4 0 6 20 0 0 50 12 
1

w bazie R, w pełni wektorowy:

df$Size*df[,5:7][cbind(1:nrow(df),df$Month)]