2016-06-22 14 views
5

Temel sorunumun tek bir dizide birden fazla diziyi nasıl düzenleyeceğimi düşünüyorum. Her ne kadar serilerim zaman içinde eşit olmasa da, hisse senedi ve kıyaslama için eşit zaman uzunluğu serilerini kullanmam bile (gerekirse el ile eşit veri sağlayabilirim) hata alıyorum. Bir piyasa modelini tahmin etmek istiyorum (yani, hisse senetlerinin her bir hisse için geri dönüşü, hisse senetleri için geri dönüşleri) ve uzun formatta regresyondan beta değerlerinin bir veri çerçevesini yapmak istiyorum. Bu nedenle, sağlanan örnek için, beta değer veri çerçevesinde 4 beta değeri (ABC için 2 ve XYZ için 2) olacaktır. Bu onların gün içi geriletebilmenin iki gün stokları ABC ve XYZ şu anki beta tahmin etmek için benim dplyr tabanlı kod iki hisse senedi fiyatlarıGruplama değişkenleri üzerinde koşullandırılmış tek bir dizide birden fazla dizi nasıl geri alınır?

idf <- structure(list(Firm = c("ABC", "ABC", "ABC", "ABC", "ABC", "ABC", "ABC", 
    "ABC", "ABC", "ABC", "ABC", "ABC", "ABC", "ABC", "ABC", "XYZ", "XYZ", "XYZ", 
    "XYZ", "XYZ", "XYZ", "XYZ", "XYZ", "XYZ", "XYZ", "XYZ", "XYZ", "XYZ", "XYZ", 
    "XYZ"), Date = structure(c(NA, 1451642400, 1451646000, 1451649600, 1451653200, 
    1451656800, 1451660400, 1451664000, 1451898000, 1451901600, 1451905200, 
    1451908800, 1451912400, 1451916000, 1451919600, NA, 1451642400, 1451646000, 
    1451649600, 1451653200, 1451656800, 1451660400, 1451664000, 1451898000, 
    1451901600, 1451905200, 1451908800, 1451912400, 1451916000, 1451919600), 
    tzone = "UTC", class = c("POSIXct", "POSIXt")), Price = c(1270.9, 1277, 
    1273.25, 1273.85, 1273.75, 1272, 1265.35, 1265.35, 1253.1, 1248.1, 1242, 
    1248.15, 1241.1, 1246.5, 1242.5, 225.75, 225.7, 225.5, 225.45, 228.6, 227.7, 
    227.8, 227.8, 226, 225.1, 222.35, 222.25, 221.1, 221.2, 220.7), rt = c(NA, 
    0.00478826614451489, -0.0029408902678254, 0.000471124032113579, 
    -7.8505259892836e-05, -0.00137484063686699, -0.00524170116535849, 0, 
    -0.00972828256347036, -0.00399808624683118, -0.00489941143098349, 
    0.00493947152112462, -0.00566437187907365, 0.00434154082813709, 
    -0.00321414499282824, NA, -0.000221508473604359, -0.000886524880757023, 
    -0.000221754075639957, 0.0138753464936165, -0.00394477829101625, 
    0.000439077943387822, 0, -0.00793305174079517, -0.00399025135959974, 
    -0.0122920309559813, -0.000449842562691316, -0.00518778653061336, 
    0.000452181784779349, -0.00226295638548901), day = structure(c(NA, 16801, 
    16801, 16801, 16801, 16801, 16801, 16801, 16804, 16804, 16804, 16804, 16804, 
    16804, 16804, NA, 16801, 16801, 16801, 16801, 16801, 16801, 16801, 16804, 
    16804, 16804, 16804, 16804, 16804, 16804), class = "Date")), 
    .Names = c("Firm", "Date", "Price", "rt", "day"), 
    row.names = c(NA, -30L), class = c("tbl_df", "data.frame")) 

bir numune ve ardından benchmark endeksi

imdf <- structure(list(Date = structure(c(NA, 1451642400, 1451646000, 1451649600, 
    1451653200, 1451656800, 1451660400, 1451664000, 1451898000, 1451901600, 
    1451905200, 1451908800, 1451912400, 1451916000, 1451919600, 1451923200), 
    class = c("POSIXct", "POSIXt"), tzone = "UTC"), Price = c(3443.1, 3450.5, 
    3453.85, 3447.9, 3456.9, 3468.45, 3472.1, 3472.1, 3484.75, 3466.45, 3417.5, 
    3416.05, 3401, 3425.75, 3425.25, 3425.25), rt = c(NA, 0.0021469197059254, 
    0.000970402793278424, -0.00172420081111291, 0.00260688364525663, 
    0.00333557458000655, 0.00105178994070698, 0, 0.0036367074012027, 
    -0.00526529010184795, -0.0142217259100423, -0.000424376794422088, 
    -0.00441540679648789, 0.00725091981911596, -0.000145964093093198, 
    0), day = structure(c(NA, 16801, 16801, 16801, 16801, 16801, 16801, 16801, 
    16804, 16804, 16804, 16804, 16804, 16804, 16804, 16804), class = "Date")), 
    .Names = c("Date", "Price", "rt", "day"), row.names = c(NA, -16L), 
    class = c("tbl_df", "tbl", "data.frame")) 

bir örnek olduğunu benchmark iadesine dönün.

require(dplyr) 
q3 <- idf %>% 
    group_by(Firm, day) %>% 
    summarise(Beta = PerformanceAnalytics::CAPM.beta(idf$rt, imdf$rt)) %>% 
    na.omit() 

Ama şu hatayı veriyor:

Error: The data cannot be converted into a time series. If you are trying to pass in names from a data object with one column, you should use the form 'data[rows, columns, drop = FALSE]'. Rownames should have standard date formats, such as '1985-03-15'. 

aşağıdaki hatayı alıyorum

q3 <- idf %>% 
group_by(Firm, day) %>% 
summarise(Beta = coef(summary(lm(idf$rt~imdf$rt)))[2,1]) %>% 
na.omit() 

için:

Error: error in evaluating the argument 'object' in selecting a method for function 'summary': Error in model.frame.default(formula = idf$rt ~ imdf$rt, drop.unused.levels = TRUE) : variable lengths differ (found for 'imdf$rt')` 

Ben de agrega dayanan aşağıdaki çalıştı işlevi:

beta.est= function(x) coef(summary(lm(x~imdf$rt)))[2,1] 
betas = aggregate(cbind(rt) ~ Firm + day , idf, FUN = beta.est) 

Ama aynı zamanda aynı hatayı veriyor:

Error in summary(lm(x ~ imdf$rt)) : error in evaluating the argument 'object' in selecting a method for function 'summary': Error in model.frame.default(formula = x ~ imdf$rt, drop.unused.levels = TRUE) : variable lengths differ (found for 'imdf$rt') 

Sonra 'döngüsü için' denenmiş: Yine

betas=list() 
for(i in idf$Firm){ 
for(j in idf$day){ 
    betas$day= coef(summary(lm(idf[i,4]|j~imdf$rt|j)))[2,1]}} 

, bu alın:

Error in summary(lm(idf[i, 4] | j ~ imdf$rt | j)) : error in evaluating the argument 'object' in selecting a method for function 'summary': Error in model.frame.default(formula = idf[i, 4] | j ~ imdf$rt | j, drop.unused.levels = TRUE) : variable lengths differ (found for 'imdf$rt | j') 

Hisse senedi ve kıyaslama için eşit zaman aralığı serilerini kullandığımda aşağıdaki erroyu alırım r:

Error in summary(lm(idf[i, 4] | j ~ imdf$rt | j)) : error in evaluating the argument 'object' in selecting a method for function 'summary': Error in model.frame.default(formula = idf[i, 4] | j ~ imdf$rt | j, drop.unused.levels = TRUE) : variable lengths differ (found for 'imdf$rt | j') 

Ben de stoklarında kıyaslama indeksi lag gerileme eğer yukarıdaki kodlar mevcut beta değerleri tahmin için, çok güzel olurdu rağmen. Lütfen bana yardım et.

+0

Değişkenlerinizin uzunluğu, Firmanın ve 'day'ın bir araya getirilmesinden daha kısadır; buradaki temel sorun, lm' işleviyle ilgilidir. Aksi takdirde, sadece "idf%>% group_by (Firma, gün)%>% summarise_each (eğlenceler (beta.est))" çalışırdı. –

+0

bir birleştirme belki 'IDF%>% group_by (Firma, gün)%>% left_join (imdf, = "bir gün")%>% özetlemek (Beta = katsayısı (özet (lm (. $ Rt.x ~. $ Rt .Y))) [2,1]) '? Hala ne yapmaya çalıştığınızdan emin değilsiniz –

+0

Okay @DavidArenburg. adım adım. ABC'nin getirileri bağımlı değişkendir ve Tezgahın dönüşleri 1. günde bağımsız değişkendir. ABC'nin getirileri bağımlı değişkendir ve Bench'in dönüşleri 2. günde bağımsız değişkendir. XYZ'nin dönüşleri bağımlı değişkendir ve Bench'in dönüşleri 1. günde bağımsız değişkendir. XYZ'nin getirileri bağımlı değişkendir ve Bench'in dönüşleri 2. günde bağımsız değişkendir.Kendimi netleştirdim mi? –

cevap

5

Umarım bazı ek paketler kullanmamın sakıncası yoktur.Gerçekten çoklu doğrusal regresyon ile çalışan simplifys ben fikrimin bir dplyr kombinasyonu, tidyr, purrr ve broom:

Elimizde bazı kriterler adı eklemek kriter sütun adları ile veri sütun adları karıştırmayın sağlamak için:

names(imdf) <- paste("bm1", names(imdf), sep ="_") 

Ayrıcagöre gruplandırmak için veri var başka kriter

set.seed(123) 
imdf$bm1_Date_lag <- imdf$bm1_Date - 3600  # shift Date by 1 hour 
imdf$bm2_rt <- rnorm(nrow(imdf), sd = 0.005) # add a dummy benchmark 

İlk gecikmeli tarihi değişken eklemek ve/veya katılabilir 193.210 ve day, o bu tüm diğer değişkenleri içeren her bir grup bir data.frame denilen data için oluşturduğu kriter Date üzerine veri ve yuva ile katılmak. Her grup bir doğrusal modele uyan ve purrr den map ile yeni bir sütun olarak ekleyebilirsiniz böylece

idf_grouped <- idf %>% group_by(Firm, day) %>% 
    left_join(imdf, by = c("Date" = "bm1_Date")) %>% 
    nest() 

day değerler olmadan grupları kaldırın. Tek adımda birden fazla model için bunu yapabilirsiniz. işlemek için daha kolay - dplyr bağlamında - öyle bir data.frame döndürdüğü için
idf_grouped <- idf_grouped %>% filter(!is.na(day)) %>% 
    mutate(model = map(data,~lm(rt~bm1_rt, data = .)), 
      model2 = map(data,~lm(rt~bm2_rt, data = .))) 

ben broom den tidy tercih doğrusal modellerin katsayıları çıkarmak için. unnest(), verilerinizi tek bir data.frame haline dönüştürür. Eğer kesişmesine ilgilenmiyor Çünkü kriterler sadece ilk adımı sırasında "Date" = "bm1_Date_lag" tarafından katılmak gecikmeli bu betas hesaplamak için bm1_rt

idf_grouped %>% 
    unnest(bm1 = model %>% map(tidy, quick = TRUE), 
      bm2 = model2 %>% map(tidy, quick = TRUE),.sep = "_") %>% 
    filter(bm1_term == "bm1_rt") 
## Firm  day bm1_term bm1_estimate bm2_term bm2_estimate 
## <chr>  <date> <fctr>  <dbl> <fctr>  <dbl> 
## 1 ABC 2016-01-01 bm1_rt 0.08879514 bm2_rt -0.2781275 
## 2 ABC 2016-01-04 bm1_rt 0.25888489 bm2_rt 0.3845765 
## 3 XYZ 2016-01-01 bm1_rt 0.66791986 bm2_rt -0.2891714 
## 4 XYZ 2016-01-04 bm1_rt 0.45735812 bm2_rt -0.5014824 

için filtre.

Düzenleme: Bir endüstri dönüşü uygulamak için, her bir firmanın ait olduğu bir eşleştirmeye sahip olmanız gerekir. illüstrasyon amaçla ben sadece ben sadece idf_2

idf_map <- idf_2 %>% left_join(firm_map, by = "Firm") 

içine bu katılıp mesela hesaplamak "ABC"

idf_2 <- idf %>% filter(Firm == "XYZ") %>% mutate(Firm = "DEF") %>% bind_rows(idf) 
firm_map <- data.frame(Firm = c("ABC", "DEF", "XYZ"), Industry = c(1,1,2), stringsAsFactors = FALSE) 

aynı sektörüne eşleştirmek olduğunu "XYZ" bir kopyası gibi başka firma "DEF" eklendi. Şimdi ind_rt Regresyondaki açıklayıcı değişken olarak kullanılabilecek her sektörün ortalama getiri

idf_map %>% left_join(idf_map %>% group_by(Industry, Date) %>% 
    summarise(ind_rt = mean(rt, na.rm = TRUE)), by = c("Industry", "Date")) 

.

+0

Teşekkür ederiz @wici, Lütfen ayrıca referans ölçütün 1'ini de belirtin. bazı sorgular: rt.x = stoklara geri dönüyor ve rt.y = ölçüme geri dönüyor mu ?, ilk önce benchmark'ı idf'e birleştirmek mümkün mü? Firmanın ve idf $ altında tarihler Firması'nda yığılır ve sonra lm veya plm kullanılır. paketleri ?, Yukarıdaki süreç içine daha fazla kriter (BM1, BM2) dahil edilebilir mi ?, –

+0

cevapları cevaplamak için lütfen soruları cevaplayın @wici. –

+0

@PolarBu son zamanlarda biraz meşgulüm, cevabımı düzenledim. İkinci sorgunuzu anladığımdan emin değilim, her bir Firm için benchmark 'Date' değerlerinin eşleştirilmesiyle birleştirildi. Günlük değerlendirmelere ihtiyacınız var, böylece verilerinizi buna göre ayırmanız (gruplamanız) gerekir. – wici

İlgili konular