R: Назначение переменной квинтилю ежемесячно

Я пытаюсь в R указать, в каком квинтиле находится значение переменной для каждого месяца моего фрейма данных в этом случае на основе волатильности. Для каждого месяца я хочу знать для каждой акции, находится ли она в наиболее волатильном квинтиле или в одном из других.

До сих пор я придумал следующую функцию (см. ниже). К сожалению, функция работает только в некоторых случаях и часто выдает следующую ошибку:

Error in cut.default(df$VOLATILITY, unique(breaks), label = FALSE, na.rm =TRUE): 
  invalid number of intervals

Не могли бы вы дать мне несколько советов, как улучшить этот код, чтобы он работал правильно.

Это относительно срочно. Большое спасибо!

quintilesVolByMonth <- function(x){
  months<-as.vector(unique(x$DATE))  
  dfx<-data.frame()
  for(n in seq(1,length(months))){
    num<-5
    print(paste("Appending month",months[n],sep=""))
    df<-subset(x,DATE==months[n])
    breaks<-quantile(df$VOLATILITY,probs=seq(0,1, 1/num),na.rm=TRUE)
    df$volquintile <- cut(df$VOLATILITY,unique(breaks), 
                       label=FALSE, na.rm=TRUE)
    dfx<-rbind(dfx,df)
  }
  return(dfx)
}
Frame.Quintile <- quintilesVolByMonth(x)   

ПРИМЕР ДАННЫХ: Последний столбец — это то, что я пытаюсь получить. Приведенные здесь данные являются лишь примером, а не фактическими результатами.

> DATE <- c("01/10/2011","01/10/2012","01/10/2010","01/08/2010","01/10/2011","01/12/2011","01/09/2011","01/10/2011","01/09/2012","01/08/2012","01/02/2010","01/01/2011","01/09/2010","01/06/2010","01/07/2010","01/01/2012","01/01/2012","01/11/2011","01/09/2011","01/10/2011")
> NAME<-c("HOEK'S MACHINE DEAD - DELIST.","WORLD SCOPE (CADB TEST STOCK)","BRILL (KON.)",   "BBL DEAD - 30/06/465", "GENK LOGISTICS","GROENIJK.YLCBN. DEAD - DELIST.31/05/479", "NOORD-EUR.HOUTH.","PALTHE DEAD - 4/2/475","GENERALE BANQUE DEAD - DEL. 30/12/490","STORK DEAD - TAKEOVER 905099","LOUVAIN-LA-NEUVE","VENTOS DEAD - 06/06/384","BRAINE-LE-COMTE SUSP 14/02/460","VILENZO DEAD - 25/11/370","ECONOSTO KON. DEAD - 07/07/374","ELECTRORAIL DEAD - DELIST 21/02/387","BLYSTEIN FL.1384","OBOURG (CIMENTS)","BRUGEFI DEAD - 31/07/475","GIB NEW")
> VOLATILITY<-c(0.3383, 0.084,  0.046,  0.0945, 0.0465, 0.2008, 0.1361, 0.2183, 0.1032, 0.1083, 0.0494, 0.0538, 0.0357, 0.037,  0.0386, 0.073,  0.073,  0.0393, 0.0687, 0.3308)
> VOLQUINTILE<-c(4,1,1,2,2,3,2,3,4,2,3,2,4,1,2,1,1,2,3,4)
>   
> x<-data.frame(DATE,NAME,VOLATILITY, VOLQUINTILE)
> x
         DATE                                    NAME VOLATILITY VOLQUINTILE
1  01/10/2011           HOEK'S MACHINE DEAD - DELIST.     0.3383           4
2  01/10/2012           WORLD SCOPE (CADB TEST STOCK)     0.0840           1
3  01/10/2010                            BRILL (KON.)     0.0460           1
4  01/08/2010                    BBL DEAD - 30/06/465     0.0945           2
5  01/10/2011                          GENK LOGISTICS     0.0465           2
6  01/12/2011 GROENIJK.YLCBN. DEAD - DELIST.31/05/479     0.2008           3
7  01/09/2011                        NOORD-EUR.HOUTH.     0.1361           2
8  01/10/2011                   PALTHE DEAD - 4/2/475     0.2183           3
9  01/09/2012   GENERALE BANQUE DEAD - DEL. 30/12/490     0.1032           4
10 01/08/2012            STORK DEAD - TAKEOVER 905099     0.1083           2
11 01/02/2010                        LOUVAIN-LA-NEUVE     0.0494           3
12 01/01/2011                 VENTOS DEAD - 06/06/384     0.0538           2
13 01/09/2010          BRAINE-LE-COMTE SUSP 14/02/460     0.0357           4
14 01/06/2010                VILENZO DEAD - 25/11/370     0.0370           1
15 01/07/2010          ECONOSTO KON. DEAD - 07/07/374     0.0386           2
16 01/01/2012     ELECTRORAIL DEAD - DELIST 21/02/387     0.0730           1
17 01/01/2012                        BLYSTEIN FL.1384     0.0730           1
18 01/11/2011                        OBOURG (CIMENTS)     0.0393           2
19 01/09/2011                BRUGEFI DEAD - 31/07/475     0.0687           3
20 01/10/2011                                 GIB NEW     0.3308           4

person user2251017    schedule 06.04.2013    source источник
comment
воспроизводимый пример, пожалуйста?   -  person Ben Bolker    schedule 06.04.2013
comment
Я согласен с Беном. В качестве небольшого примечания: имейте в виду, что если вы когда-нибудь примените этот код к средним/большим объемам данных, он будет очень медленным. Создание пустого фрейма данных, а затем добавление в него фрагментов, как правило, очень неэффективно.   -  person joran    schedule 06.04.2013
comment
Я добавил пример. Как вы думаете, какой метод был бы более эффективным, Джоран?   -  person user2251017    schedule 06.04.2013
comment
months<-as.vector(unique(x$DATE)) скорее даст вам уникальные дни, чем уникальные месяцы. Вероятно, вы получаете слишком мало элементов для правильного формирования квинтилей.   -  person IRTFM    schedule 06.04.2013
comment
Есть ли способ пропустить месяцы, в течение которых слишком мало элементов?   -  person user2251017    schedule 06.04.2013


Ответы (1)


Это работает для вас?

library(plyr)
vol1<-ddply(mydata,.(DATE), transform, max.name=NAME[which.max(quantile(VOLATILITY))])
             DATE                                    NAME VOLATILITY                                max.name
    1  01/01/2011                 VENTOS DEAD - 06/06/384     0.0538                 VENTOS DEAD - 06/06/384
    2  01/01/2012     ELECTRORAIL DEAD - DELIST 21/02/387     0.0730     ELECTRORAIL DEAD - DELIST 21/02/387
    3  01/01/2012                        BLYSTEIN FL.1384     0.0730     ELECTRORAIL DEAD - DELIST 21/02/387
    4  01/02/2010                        LOUVAIN-LA-NEUVE     0.0494                        LOUVAIN-LA-NEUVE
    5  01/06/2010                VILENZO DEAD - 25/11/370     0.0370                VILENZO DEAD - 25/11/370
    6  01/07/2010          ECONOSTO KON. DEAD - 07/07/374     0.0386          ECONOSTO KON. DEAD - 07/07/374
    7  01/08/2010                    BBL DEAD - 30/06/465     0.0945                    BBL DEAD - 30/06/465
    8  01/08/2012            STORK DEAD - TAKEOVER 905099     0.1083            STORK DEAD - TAKEOVER 905099
    9  01/09/2010          BRAINE-LE-COMTE SUSP 14/02/460     0.0357          BRAINE-LE-COMTE SUSP 14/02/460
    10 01/09/2011                        NOORD-EUR.HOUTH.     0.1361                                    <NA>
    11 01/09/2011                BRUGEFI DEAD - 31/07/475     0.0687                                    <NA>
    12 01/09/2012   GENERALE BANQUE DEAD - DEL. 30/12/490     0.1032   GENERALE BANQUE DEAD - DEL. 30/12/490
    13 01/10/2010                            BRILL (KON.)     0.0460                            BRILL (KON.)
    14 01/10/2011           HOEK'S MACHINE DEAD - DELIST.     0.3383                                    <NA>
    15 01/10/2011                          GENK LOGISTICS     0.0465                                    <NA>
    16 01/10/2011                   PALTHE DEAD - 4/2/475     0.2183                                    <NA>
    17 01/10/2011                                 GIB NEW     0.3308                                    <NA>
    18 01/10/2012           WORLD SCOPE (CADB TEST STOCK)     0.0840           WORLD SCOPE (CADB TEST STOCK)
    19 01/11/2011                        OBOURG (CIMENTS)     0.0393                        OBOURG (CIMENTS)
    20 01/12/2011 GROENIJK.YLCBN. DEAD - DELIST.31/05/479     0.2008 GROENIJK.YLCBN. DEAD - DELIST.31/05/479

Обновленное решение:

library(plyr)    


   vol2<-ddply(x,.(DATE), transform,quantile=ifelse(VOLATILITY<quantile(VOLATILITY,p=0.25),1,
ifelse(((VOLATILITY>quantile(VOLATILITY,p=0.25))& (VOLATILITY<quantile(VOLATILITY,p=0.5))),2,ifelse(((VOLATILITY>quantile(VOLATILITY,p=0.5))& VOLATILITY<quantile(VOLATILITY,p=0.75)),3,4))))

       DATE                                    NAME VOLATILITY   quantile
1  01/01/2011                 VENTOS DEAD - 06/06/384     0.0538        4
2  01/01/2012     ELECTRORAIL DEAD - DELIST 21/02/387     0.0730        4
3  01/01/2012                        BLYSTEIN FL.1384     0.0730        4
4  01/02/2010                        LOUVAIN-LA-NEUVE     0.0494        4
5  01/06/2010                VILENZO DEAD - 25/11/370     0.0370        4
6  01/07/2010          ECONOSTO KON. DEAD - 07/07/374     0.0386        4
7  01/08/2010                    BBL DEAD - 30/06/465     0.0945        4
8  01/08/2012            STORK DEAD - TAKEOVER 905099     0.1083        4
9  01/09/2010          BRAINE-LE-COMTE SUSP 14/02/460     0.0357        4
10 01/09/2011                        NOORD-EUR.HOUTH.     0.1361        4
11 01/09/2011                BRUGEFI DEAD - 31/07/475     0.0687        1
12 01/09/2012   GENERALE BANQUE DEAD - DEL. 30/12/490     0.1032        4
13 01/10/2010                            BRILL (KON.)     0.0460        4
14 01/10/2011           HOEK'S MACHINE DEAD - DELIST.     0.3383        4
15 01/10/2011                          GENK LOGISTICS     0.0465        1
16 01/10/2011                   PALTHE DEAD - 4/2/475     0.2183        2
17 01/10/2011                                 GIB NEW     0.3308        3
18 01/10/2012           WORLD SCOPE (CADB TEST STOCK)     0.0840        4
19 01/11/2011                        OBOURG (CIMENTS)     0.0393        4
20 01/12/2011 GROENIJK.YLCBN. DEAD - DELIST.31/05/479     0.2008        4
person Metrics    schedule 06.04.2013
comment
Да частично, только я хотел бы знать, что акция X находится в квантиле 2, а акция Y — в квантиле 4 и так далее... - person user2251017; 06.04.2013
comment
Последний столбец - это результат, который я пытаюсь получить. - person user2251017; 06.04.2013
comment
Если вы просматриваете каждый месяц, то я не думаю, что ваш ожидаемый результат — это то, что вы на самом деле ожидаете. Смотрите мои обновленные ответы. - person Metrics; 07.04.2013
comment
Это результат, который я искал. Единственная оставшаяся проблема заключается в том, что когда для некоторых значений волатильность равна нулю, решение не работает должным образом. Есть ли способ обойти это? - person user2251017; 08.04.2013
comment
Пожалуйста, проверьте здесь : As long as VOLATILITY is numeric vector there shouldn't be any problem. Note that NA and NaN values are not allowed in numeric vectors unless na.rm is TRUE. - person Metrics; 08.04.2013
comment
VOLATILITY действительно является числовым фактором. Ошибка не отображается, но проблема в том, что функция присваивает много значений в самые ранние годы квартилю 1 и почти не присваивает значения квартилю 4 в последние годы моего набора данных. Таким образом, каждый квартиль содержит все меньше и меньше значений и все меньше и меньше более поздних лет ... Не уверен, что понятно, что я пытаюсь сказать. - person user2251017; 08.04.2013
comment
Обратите внимание, что quantile формируется для каждой уникальной даты. Таким образом, квартиль одной даты не имеет ничего общего с квартилем других дат. Но это зависит от того, сколько наблюдений у вас есть в каждую дату. Если это не отвечает на то, что вы ищете, попробуйте опубликовать новый вопрос по этому поводу с воспроизводимым примером (с выводом). - person Metrics; 09.04.2013