2010-10-07 7 views
3

У меня есть вопрос о ddply и подмножестве.Классифицировать или вырезать фрейм данных по списку диапазона классов и суммировать его с помощью ddply

У меня есть dataframe ДФ, как это:

df <- read.table(textConnection(
" id v_idn v_seed v_time v_pop v_rank v_perco 
    1 15 125648 0  150 1  15  
    2 17 125648 0  120 2  5  
    3 18 125648 0  100 3  6  
    4 52 125648 0  25 4  1  

    5 17 125648 10  220 1  5  
    6 15 125648 10  160 2  15  
    7 18 125648 10  110 3  6  
    8 52 125648 10  50 4  1  

    9 56 -11152 0  250 1  17  
    10 15 -11152 0  180 2  15  
    11 18 -11152 0  110 3  6  
    12 22 -11152 0  5  4  14  

    13 56 -11152 10  250 1  17  
    14 15 -11152 10  180 2  15  
    15 22 -11152 10  125 3  14  
    16 18 -11152 10  120 4  6 "), header=TRUE)  

ШАГ ПЕРВЫЙ:

У меня есть список равного интервала с cut_interval так:

myinterval <- cut_interval(c(15,5,6,1,17,14), length=10) 

Так у меня есть два здесь: [0,10) и (10,20)

ШАГ ВТОРОЙ:

Я хочу, чтобы каждая группа/класс определяют два моих уровней в v_cut ... как это:

id v_idn v_seed v_time v_pop v_rank v_perco v_cut 
1 15 125648 0  150 1  15  (10,20] 
2 17 125648 0  120 2  5  [0,10) 
3 18 125648 0  100 3  6  [0,10) 
4 52 125648 0  25 4  1  [0,10) 

5 17 125648 10  220 1  5  [0,10) 
6 15 125648 10  160 2  15  (10,20] 
7 18 125648 10  110 3  6  [0,10) 
8 52 125648 10  50 4  1  [0,10) 

9 56 -11152 0  250 1  17  (10,20] 
10 15 -11152 0  180 2  15  (10,20] 
11 18 -11152 0  110 3  6  [0,10) 
12 22 -11152 0  5  4  14  (10,20] 

13 56 -11152 10  250 1  17  (10,20] 
14 15 -11152 10  180 2  15  (10,20] 
15 22 -11152 10  125 3  14  (10,20] 
16 18 -11152 10  120 4  6  [0,10) 

ШАГ 3:

Я хочу знать изменчивость v_rank для оси x и время для оси y для каждой группы v_cut, поэтому мне нужно вычислить min, mean, max, sd для значения v_rank с чем-то вроде

ddply(df, .(v_cut,v_time), summarize ,mean = mean(v_rank), min = min(v_rank), max = max(v_rank), sd = sd(v_rank)) 

* РЕЗУЛЬТАТ Разыскивается: *

id v_time MEAN.v_rank ... v_cut 
1 0  2.25   (10,20] 
2 0  2.42   [0,10) 
3 10  2.25   [0,10) 
4 10  2.42   (10,20] 

МОЯ ПРОБЛЕМА

Я не знаю, как пройти шаг 1 -> Шаг 2:/

И если это возможно group by v_cut, как мой пример на шаге 3?

Есть ли возможность сделать то же самое с опцией «подмножество» ddply?

Еще раз, большое спасибо за вашу помощь великого гуру R!

UPDATE 1:

У меня есть ответ, чтобы пойти шаг1 к step2:

df$v_cut <- cut_interval(df$v_perco,n=10) 

Я использую plyr, но, возможно, есть лучший ответ в этом случае?

Ответ на переход к шагу 2-го шага 3?

UPDATE 2:

Брэндон Bertelsen дать мне хороший ответ с расплавом + гипсом, но теперь (понимать) я хочу сделать ту же операцию с plyr и ddply ..с другим результатом:

id v_idn v_time MEAN.v_rank ... v_cut 
    1 15 0  2.25   (10,20] 
    2 15 10  2.45   (10,20] 
    2 17 0  1.52   [0,10) 
    2 17 10  2.42   [0,10) 
    etc. 

Я пытаюсь что-то вроде этого:

r('sumData <- ddply(df, .(v_idn,v_time), summarize,min = min(v_rank),mean = mean(v_rank), max = max(v_rank), sd=sd(v_rank))') 

Но я хочу иметь v_cut в моем sumData dataframe, как я могу сделать с ddply? есть ли возможность сделать это? Или слияние с начальным df и ключом = v_idn для добавления столбца v_cut в sumData является единственным хорошим ответом?

+1

Немного тестовых данных из dput (head (df), 5) поможет. –

+0

Для обновления 2: Я не уверен, как вы рассчитали 2.25. Потому что в вашей таблице примеров, где: v_idn = 15 & v_time = 0, мы имеем v_rank n = 2, sum = 3 (1 + 2), поэтому среднее значение будет равно сумме/n = 1.5. –

ответ

2

Вам не нужно plyr для этого, вы можете использовать reshape

## Pull what you need 
dfx <- df[c("v_seed", "v_time","v_rank","v_perco")] 
## Bring in your cuts 
dfx <- data.frame(dfx, ifelse(df$v_perco > 10,"(10,20]", "[0,10)"))) 
## Rename v_cut 
colnames(dfx)[ncol(dfx)] <- "v_cut"  
## Melt it.  
dfx <- melt(dfx, id=c("v_cut", "v_seed", "v_time")) 
## Cast it. 
dfx <- cast(dfx, v_cut + v_time + v_seed ~ variable, c(mean,min,max,sd)) 

, если вы хотите только среднее, а затем заменить последнюю строку с:

dfx <- cast(dfx, v_cut + v_time + v_seed ~ variable, mean) 

типа "DFX" и вы увидите фрейм данных с тем, что вы просили.

+0

Thx для помощи, я пытаюсь ваше решение, но у меня есть проблема с линией «cast», «bound» не существует в df dataframe. у вас есть хорошая документация для этой функции, потому что? cast или? melt look cryptic: s – reyman64

+0

whoopsie, «bound» должен быть v_cut –

+0

Я не уверен, что вы хотите от v_cut, предоставленные сокращения не разбивают его на ящики 10, но, скорее, n = 10, означает 10 бункеров. Я думаю, что вы хотите cut_interval (x, length = 10). –

2

Вы просто возникли проблемы с синтаксисом все:

## Add your cut 
df.new <- data.frame(df, ifelse(df$v_perco > 10,"(10,20]", "[0,10)")) 
## Rename v_cut 
colnames(df.new)[ncol(df.new)] <- "v_cut" 

## Careful here read the note below 
df.new <- ddply(df.new, .(v_idn, v_time), function(x) unique(data.frame(
mean = mean(x$v_rank), 
v_cut = x$v_cut 
))) 

В качестве альтернативы:

ddply(df.new, .(v_idn, v_time), summarise, mean=mean(v_rank)) 

С "(v_idn, v_time)" вы говорите ddply, что для каждой комбинации v_idn и v_time, вы хотите, чтобы он вычислил среднее значение v_rank.