Написание функции OLS для запуска регрессии на значениях фрейма больших данных

У меня есть мегафрейм данных, содержащий ежемесячную доходность акций с января 1970 года по декабрь 2009 года (строки) для 7 разных стран, включая США (столбцы). Моя задача состоит в том, чтобы регрессировать доходность акций каждой страны (зависимая переменная) по доходности акций США (независимая переменная), используя значения 4 разных периодов времени, а именно 70-х, 80-х, 90-х и 00-х годов.

Набор данных (.csv) можно загрузить по адресу: https://docs.google.com/file/d/0BxaWFk-EO7tjbG43Yl9iQVlvazQ/edit

Это означает, что у меня есть 24 регрессии, которые нужно запустить отдельно и сообщить о результатах, что я уже сделал с помощью функции lm(). Однако в настоящее время я пытаюсь использовать R более разумно и создавать собственные функции, которые будут достигать моей цели и давать 24 набора результатов.

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

seventies = mydata[1:120, ] # 1970s (from Jan. 1970 to Dec. 1979)
eighties = mydata[121:240, ] # 1980s (from Jan. 1980to Dec. 1989)
nineties = mydata[241:360, ] # 1990s (from Jan. 1990 to Dec. 1999)
twenties = mydata[361:480, ] # 2000s (from Jan. 2000 to Dec. 2009)

NB: Каждая из вновь созданных переменных представляет собой матрицы 120 x 7 для 120 наблюдений в 7 странах.

Выполнение 24 регрессий с использованием Java потребовало бы использования объединенных for циклов.

Может ли кто-нибудь предоставить шаги, которые я должен предпринять, чтобы написать функцию, которая приведет к желаемому результату? Некоторые фрагменты кода R также будут оценены. Я также думаю, что будет использоваться функция mapply.

Спасибо и дайте мне знать, если мой пост нуждается в редактировании.


person SavedByJESUS    schedule 29.01.2013    source источник
comment
Если вам нужны только советы по эффективному кодированию R, это, вероятно, должно перейти к переполнению стека. Если вам нужен совет о том, является ли lm хорошим инструментом для этой цели или какой может быть альтернативная стратегия, которая может учитывать характер данных временных рядов, это нормально (но вы не задавали этот вопрос). Хотя в нынешнем виде я не совсем понимаю цель упражнения - 24 модели для соответствия не кажутся чрезмерными, даже если вы делаете это, вырезая и вставляя строку кода 24 раза, а набор данных довольно мал, что необходимость найти эффективный способ сделать это?   -  person Peter Ellis    schedule 29.01.2013
comment
@PeterEllis Как я уже объяснял ранее, я уже выполнил упражнение, используя функцию lm(), вырезая и вставляя 24 раза. Но я учусь писать функции на R, особенно как не использовать циклы, и я подумал, что это упражнение подходит для получения таких знаний, которые могут быть более полезными в будущем, так как я хочу сделать R своим основным языком программирования.   -  person SavedByJESUS    schedule 29.01.2013
comment
Я проголосовал за закрытие и переход на Stack Exchange. Я дал ответ в виде примера домашнего задания по программированию, игнорируя статистические проблемы, но обратите внимание, что использование такой регрессии с двумя временными рядами почти всегда является плохой идеей, поскольку она очень склонна давать ложные результаты.   -  person Peter Ellis    schedule 30.01.2013


Ответы (1)


Это не полный ответ, а начало.

Во-первых, я считаю ошибкой разбивать набор данных на разные объекты. Это только усложняет обработку. Лучше было бы добавить индикаторную переменную в ваш фрейм данных, например

> mydata <- as.data.frame(matrix(round(rnorm(480*7),1), ncol=7))
> names(mydata) <- c("USA", paste("country", 1:6, sep=""))
> 
> mydata$decade <- rep(c("seventies", "eighties", "nineties", "twenties"), rep(120,4))
> 
> head(mydata)
   USA country1 country2 country3 country4 country5 country6    decade
1  0.2     -0.1      0.8      0.9     -1.6     -0.1     -1.1 seventies
2  0.0     -0.5      0.1     -0.4     -1.2     -0.9      1.3 seventies
3  2.2      1.4      1.7      1.0     -1.6     -1.5      0.6 seventies
4 -0.5      2.5      0.2     -0.9      2.3      1.0      0.1 seventies
5 -0.1      0.0     -0.9     -1.4      0.7     -0.1     -0.1 seventies
6  0.3     -0.4      0.1      0.5      0.2      0.9     -0.5 seventies

Мой второй совет - преобразовать это в длинный формат, используя библиотеку reshape или reshape2, например

> library(reshape2)
> mydata.m <- melt(mydata, id.vars=c("USA", "decade"))
> head(mydata.m)
   USA    decade variable value
1  0.2 seventies country1  -0.1
2  0.0 seventies country1  -0.5
3  2.2 seventies country1   1.4
4 -0.5 seventies country1   2.5
5 -0.1 seventies country1   0.0
6  0.3 seventies country1  -0.4

Отсюда у вас есть ряд вариантов. Вы можете использовать tapply() из базы или что-то из пакета plyr. Вы даже можете подогнать ее как одну большую модель с взаимодействием между переменной и десятилетием (дает результаты, аналогичные, но не идентичные вашим 24 моделям, что позволит разделить оценки остаточной дисперсии). например, с tapply начните с:

> country <- with(mydata.m, tapply(USA, list(decade, variable), function(x){x}))
> country
          country1    country2    country3    country4    country5    country6   
eighties  Numeric,120 Numeric,120 Numeric,120 Numeric,120 Numeric,120 Numeric,120
nineties  Numeric,120 Numeric,120 Numeric,120 Numeric,120 Numeric,120 Numeric,120
seventies Numeric,120 Numeric,120 Numeric,120 Numeric,120 Numeric,120 Numeric,120
twenties  Numeric,120 Numeric,120 Numeric,120 Numeric,120 Numeric,120 Numeric,120
> country[1,1]
[[1]]
  [1]  0.2  1.1  0.2  0.1 -0.1  2.1 -2.4 -0.5 -0.5 -0.3  0.1 -0.9 -0.6 -0.1  0.8  0.9  0.4  0.6 -0.5  0.4
 [21] -1.3  0.9  0.0 -1.0  0.2 -0.2  0.0 -0.5  0.0  1.4  0.7 -0.9 -1.1  1.7  0.5 -1.0  1.1  0.1  0.3  0.8
 [41] -0.5 -1.9 -1.5 -0.2  0.5 -0.8 -1.2  1.0  0.3  1.7 -0.5  1.2 -0.1  0.9  0.9  0.5 -1.8  0.7  0.1  0.7
 [61]  0.4  0.2 -0.7  2.1  0.2 -1.1 -1.4  1.7 -0.4 -1.0  0.0  1.0 -0.6  1.5  0.4  0.3 -0.2 -1.0 -0.8  1.0
 [81]  0.4 -0.3  1.2  0.9 -0.8  0.2 -0.7 -1.3  0.4 -0.7  0.7  1.5 -0.7 -0.3 -2.3  0.3  0.6 -0.9 -0.5  0.4
[101]  0.4 -0.8  0.2  0.2  0.3 -1.0 -1.0  0.6 -2.8 -0.2  2.7  1.1 -0.5 -0.1 -0.6 -0.6 -0.2  0.1  0.0 -0.9

и так далее. Пакет plyr, вероятно, даст вам какой-нибудь элегантный способ подгонки моделей, позволяющий избежать постукивания. Дальнейшие действия будут частично зависеть от того, как вы хотите сохранить результаты модели — хотите ли вы всю модель целиком или только сводную статистику по каждой из них и т. д.

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

person Peter Ellis    schedule 29.01.2013