Манипулирование таблицей данных для регрессии Пуассона: добавление строк нулей и запаздывающих переменных

Я работаю с большим набором данных рыболовного флота, и мне нужно отформатировать его для регрессии Пуассона и других моделей подсчета. См. ниже для подмножества данных. Переменная count — «дни». p1:p3 — переменные-индикаторы для группы портов, а f1:f4 — переменные-индикаторы для другой промысловой деятельности.

yr   week   id  days rev    p1  p2 p3   f1  f2  f3  f4
2016    3   1   1   5568.3  0   1   0   0   0   0   0
2016    4   1   3   8869.53 0   1   0   0   0   0   0
2016    5   1   2   12025.8 0   1   0   0   0   0   0
2016    6   1   2   9126.6  0   1   0   0   0   0   0
2016    7   1   3   4415.4  0   1   0   0   0   0   0
2016    8   1   2   11586.6 0   1   0   0   0   0   0
2016    10  1   1   2144.4  0   1   0   0   0   0   0
2016    11  1   1   2183.25 0   1   0   0   0   0   0
2016    14  1   2   4998    0   1   0   0   0   0   0
2016    15  1   3   117     0   1   0   0   0   0   0
2016    1   2   4   12743.3 0   0   1   1   1   0   0
2016    2   2   2   7473.48 0   0   1   1   0   0   0
2016    5   2   2   8885.52 0   0   1   1   0   0   0
2016    7   2   1   15330.6 0   0   1   1   1   0   0
2016    8   2   2   3763.8  0   0   1   1   1   0   0
2016    9   2   1   2274.05 0   0   1   1   1   0   0

Эти строки представляют только активные недели, но мне нужно включить неактивные недели каждого судна. Например, для id=1 в 2016 году мне нужно добавить строки, начинающиеся с недели=1, а затем строки для недель 9, 12 и 13. Эти строки должны содержать ту же информацию в фиктивной таблице. категории (они не меняются по годам) и имеют нули в столбце «дни». Мне не нужно добавлять строки после последнего значения «неделя» для этого года и судна.

Здесь все становится очень сложно:

В столбце «Доход (оборот)» для этих вновь созданных строк мне нужно добавить средний доход за эту неделю и год для всех судов, которые используют одну и ту же группу портов (p1: p3).

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

Значение для 1-й недели для каждого судна должно быть средним значением дохода за первые 2 недели для этого судна в этом году.

Эта задача разносит мои навыки работы с данными вдребезги, и биться головой о стену становится больно. Любые предложения будут хорошо оценены! Спасибо.


person user1754348    schedule 26.02.2016    source источник
comment
Начните здесь и сообщите нам, как далеко вы продвинулись: stackoverflow.com/questions/22462405/   -  person MichaelChirico    schedule 26.02.2016
comment
Спасибо за ссылку. Я пытался понять это последние несколько часов, и кажется, что CJ может быть не тем, что мне нужно? Я не пытаюсь добавить строки для каждого возможного значения недели, а скорее отсутствующих значений недели (начиная с недели = 1) (до максимального значения недели для каждого идентификатора и сезона).   -  person user1754348    schedule 27.02.2016
comment
Возможно, я думал о способе атаки на это с помощью комбинации Excel и Access, но я действительно пытаюсь уйти от этих знакомых запасных вариантов. В любом случае отпишусь, если найду решение...   -  person user1754348    schedule 27.02.2016
comment
На самом деле тоже не добился прогресса в excel/access. Удивительно, что эта проблема не проявляется чаще на форумах статистики!   -  person user1754348    schedule 27.02.2016


Ответы (2)


Благодаря https://stackoverflow.com/users/3001626/david-arenburg и https://stackoverflow.com/users/2802241/user2802241 проблема решена. Вы можете увидеть сообщение о добавлении строк по адресу: Добавление строк в data.table в соответствии со значениями столбцов

test<-data.frame(DT %>% 
  group_by(yr, id) %>% 
  complete(week = 1:max(week)) %>% 
  replace_na(list(days = 0)) %>% 
  group_by(yr, id) %>% 
  mutate_each(funs(replace(., is.na(.), mean(., na.rm = T))), p1:f4))

    poisson<-data.table(test)
    setkey(poisson,yr,id,week)

    avrev<-poisson[,.(avrev = mean(rev,na.rm=T)),by=.(p1,p2,[p3,week,yr)]
    avrev<-transform(avrev,xyz=interaction(p1,p2,p3,week,yr,sep=''))
    poisson<-transform(poisson,xyz=interaction(tier200,tier300,tier500,week,yr,sep=''))
    poisson<-transform(poisson,uniqueid=interaction(drvid,season,sep=''))

    poisson$rev[is.na(poisson$rev)]<- avrev$avrev[match(poisson$xyz[is.na(poisson$rev)],avrev$xyz)]

    poisson[, lagrev:=c(rev[1], rev[-.N]), by=uniqueid]

Я уверен, что есть гораздо более приятный и аккуратный способ выполнить задачу, но это работает. Дэвид Аренбург также опубликовал ответ в разделе комментариев, который использует data.table для создания новых строк — см. другой пост.

person user1754348    schedule 28.02.2016

Чтобы получить средний доход по неделям, годам, p1, p2 и p3, просто используйте агрегатную функцию:

average_rev <- aggregate(rev~week+year+p1+p2+p3, data=your_dataframe, FUN=mean)

Чтобы добавить новый столбец запаздывающих доходов:

your_dataframe$lagged_rev <- c(NA, your_dataframe$rev[1:(nrow(_your_dataframe)-1)])

Чтобы получить средние обороты за последние две недели:

your_dataframe$avg_rev <- rowMeans(your_dataframe[,c('rev','lagged_rev')])

person Gaurav Bansal    schedule 26.02.2016
comment
Спасибо, но это не то, что я ищу. Первая часть предназначена для расчета среднего дохода, но первая задача, которую я пытаюсь выполнить, — добавить новые строки для заполнения средними доходами. - person user1754348; 27.02.2016
comment
Метод отложенных доходов не работает, так как когда я дохожу до конца «года», первое значение для следующего года — это просто последнее значение предыдущего года, что мне не нужно. Данные не сбалансированы! - person user1754348; 27.02.2016
comment
Для значений с запаздыванием вы можете разделить данные за все годы, чтобы у вас было несколько наборов данных для каждого года, а затем выполнить анализ с запаздыванием. Таким образом, вы не получите доход за предыдущие годы, когда будете проводить лаговый анализ. - person Gaurav Bansal; 27.02.2016
comment
Чтобы объединить исходный фрейм данных с average_rev, просто используйте функцию слияния. Сначала вам может понадобиться переименовать переменную среднего дохода в average_rev. Что-то вроде: names(average_rev)[6] <- 'avgrev' затем: newdf <- merge(your_dataframe, average_rev) - person Gaurav Bansal; 27.02.2016
comment
Спасибо Gaurav Bansal, я все еще не могу решить проблему с добавлением новых строк. Я удивлен, что это не более распространенная проблема. - person user1754348; 27.02.2016
comment
Вы можете добавлять строки, используя функцию rbind. Удачи! - person Gaurav Bansal; 27.02.2016