2013-07-09 3 views
1

Я борюсь со следующей (легкой) проблемой, но не могу найти для нее хорошего решения. Рассмотрим DF следующим образом:R colSum для двух раз в два ряда

test<-c("A","B","C","D","E","F") 
test2<-sample(1:6) 
test3<-data.frame(test,test2) 

Я хотел бы иметь третий столбец, который во втором ряду показывает соотношение количества строки 1: 2 колонки 2, в четвертой строке соотношении 3: 4 Столбец2 и в шестой строке отношение 5: 6 столбца2. Мой df намного больше, иначе я бы сделал вручную :) Любые предложения о том, как это сделать? Я знаю, что вы можете получить diff с командой diff, но соотношение? И как мне связать строки вместе? split(), похоже, не делает этого.

ответ

1

Это должно быть довольно быстро:

test3$ratio <- NA 
test3$ratio[c(FALSE, TRUE)] <- test3$test2[c(FALSE, TRUE)]/
           test3$test2[c(TRUE, FALSE)] 
+0

Nice мышления. +1 – A5C1D2H2I1M1N2O1R2T1

0

Вы можете использовать gl для генерации групп:

temp <- within(test3, { 
    Sums <- ave(test2, gl(nrow(test3)/2, 2), FUN = function(x) x[2]/x[1]) 
    Sums[c(TRUE, FALSE)] <- NA 
}) 

temp 
# test test2  Sums 
# 1 A  2  NA 
# 2 B  6 3.000000 
# 3 C  3  NA 
# 4 D  4 1.333333 
# 5 E  1  NA 
# 6 F  5 5.000000 

В качестве альтернативы (и подобные flodel отвечают), вы можете использовать head и tail:

test3$Sums <- NA 
test3$Sums[c(FALSE, TRUE)] <- (tail(c(0, test3$test2), -1)/ 
           head(c(0, test3$test2), -1))[c(FALSE, TRUE)] 
test3 
# test test2  Sums 
# 1 A  2  NA 
# 2 B  6 3.000000 
# 3 C  3  NA 
# 4 D  4 1.333333 
# 5 E  1  NA 
# 6 F  5 5.000000 

Для выше, данные выборки:

set.seed(1) 
test<-c("A","B","C","D","E","F") 
test2<-sample(1:6) 
test3<-data.frame(test,test2) 
0

Используя цикл (вместо 6 ниже вы можете поставить номер последней строки в вашем большом dataframe):

for(i in seq(2,6,by=2)) { 
test3$ratio[i] <- with(test3,test2[i-1]/test2[i]) 
} 
> test3 


    test test2  ratio 
1 A  3  NA 
2 B  5 0.6000000 
3 C  4  NA 
4 D  6 0.6666667 
5 E  1  NA 
6 F  2 0.5000000