Формирование панельных данных в R

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

Month   Beta    A   B
Jan-05  Beta1   1   32
Jan-05  Beta2   2   32
Jan-05  Beta3   3   32
Jan-05  Beta4   4   32
Jan-05  Beta5   5   32
Jan-05  Beta6   6   32
Feb-05  Beta1   7   32
Feb-05  Beta2   8   32
Feb-05  Beta3   9   32
Feb-05  Beta4   10  32
Feb-05  Beta5   11  32
Feb-05  Beta6   12  32
Mar-05  Beta1   13  32
Mar-05  Beta2   14  32
Mar-05  Beta3   15  32
Mar-05  Beta4   16  32
Mar-05  Beta5   17  32
Mar-05  Beta6   18  32
Apr-05  Beta1   19  32
Apr-05  Beta2   20  32
Apr-05  Beta3   21  32
Apr-05  Beta4   22  32
Apr-05  Beta5   23  32
Apr-05  Beta6   24  32
May-05  Beta1   25  32
May-05  Beta2   26  32
May-05  Beta3   27  32
May-05  Beta4   28  32
May-05  Beta5   29  32
May-05  Beta6   30  32
Jun-05  Beta1   31  32
Jun-05  Beta2   32  32
Jun-05  Beta3   33  32
Jun-05  Beta4   34  32
Jun-05  Beta5   35  32
Jun-05  Beta6   36  32
Jul-05  Beta1   37  32
Jul-05  Beta2   38  32
Jul-05  Beta3   39  32
Jul-05  Beta4   40  32
Jul-05  Beta5   41  32
Jul-05  Beta6   42  32
Aug-05  Beta1   43  32
Aug-05  Beta2   44  32
Aug-05  Beta3   45  32
Aug-05  Beta4   46  32
Aug-05  Beta5   47  32
Aug-05  Beta6   48  32
Sep-05  Beta1   49  32
Sep-05  Beta2   50  32
Sep-05  Beta3   51  32
Sep-05  Beta4   52  32
Sep-05  Beta5   53  32
Sep-05  Beta6   54  32
Oct-05  Beta1   55  32
Oct-05  Beta2   56  32
Oct-05  Beta3   57  32
Oct-05  Beta4   58  32
Oct-05  Beta5   59  32
Oct-05  Beta6   60  32
Nov-05  Beta1   61  32
Nov-05  Beta2   62  32
Nov-05  Beta3   63  32
Nov-05  Beta4   64  32
Nov-05  Beta5   65  32
Nov-05  Beta6   66  32
Dec-05  Beta1   67  32
Dec-05  Beta2   68  32
Dec-05  Beta3   69  32
Dec-05  Beta4   70  32
Dec-05  Beta5   71  32
Dec-05  Beta6   72  32

Как можно заметить, для каждого месяца рассчитывались шесть отдельных показателей Beta1, Beta2, Beta3, Beta4, Beta5 и Beta6. Теперь я хочу изменить это следующим образом

Month   Company Beta1   Beta2   Beta3   Beta4   Beta5   Beta6
Jan-05  A        1         2      3       4        5    6
Feb-05  A        7         8      9       10       11   12
Mar-05  A       13        14      15      16       17   18
Apr-05  A       19        20      21      22       23   24
May-05  A       25        26      27      28       29   30
Jun-05  A       31        32      33      34       35   36
Jul-05  A       37        38      39      40       41   42
Aug-05  A       43        44      45      46       47   48
Sep-05  A       49        50      51      52       53   54
Oct-05  A       56        57      58      59       60   61
Nov-05  A       62        63       64     65       66   67
Dec-05  A       68        69       70      71     72    73
Jan-05  B       32        32       32      32     32    32
Feb-05  B       32        32       32      32     32    32
Mar-05  B       32        32       32      32     32    32
Apr-05  B       32        32       32      32     32    32
May-05  B       32        32       32      32     32    32
Jun-05  B       32        32       32      32     32    32
Jul-05  B       32        32       32      32     32    32
Aug-05  B       32        32       32      32     32    32
Sep-05  B       32        32       32      32     32    32
Oct-05  B       32        32       32      32     32    32
Nov-05  B       32        32       32      32     32    32
Dec-05  B       32        32       32      32     32    32

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


person Community    schedule 24.02.2016    source источник
comment
Что определяет компанию в первом наборе данных?   -  person Raad    schedule 24.02.2016
comment
Заголовки столбцов A и B - это названия компаний.   -  person    schedule 24.02.2016
comment
Это похожее, но не точное название stackoverflow.com/questions/35324746/   -  person Pierre L    schedule 24.02.2016


Ответы (3)


Это классика recast. Аргумент id.var переходит к melt, остальные аргументы идут к dcast.

Первая функция melt создает длинный фрейм данных, указанный в id.var=c("Month", "Beta"). Следовательно, выходные данные объединят столбцы «A» и «B» в столбец с именем variable и создадут отдельный столбец value. С этим расплавленным data.frame Мы можем затем широко использовать dcast. Формула Month+variable ~ Beta имеет переменные id слева от тильды (~) и переменные меры справа. Обе функции объединены в recast для удобства.

Если порядок имеет значение, преобразуйте столбец Месяц в даты и порядок в конце:

library(zoo)
library(reshape2)
df[,1] <- as.yearmon(df[,1], "%b-%y")
newdf <- recast(df, id.var=c("Month", "Beta"), Month+variable~Beta, value.var="value")
newdf <- newdf[order(newdf$variable,newdf$Month),]
newdf[,1] <- format(newdf$Month, "%b-%y")
newdf
#     Month variable Beta1 Beta2 Beta3 Beta4 Beta5 Beta6
# 1  Jan-05        A     1     2     3     4     5     6
# 3  Feb-05        A     7     8     9    10    11    12
# 5  Mar-05        A    13    14    15    16    17    18
# 7  Apr-05        A    19    20    21    22    23    24
# 9  May-05        A    25    26    27    28    29    30
# 11 Jun-05        A    31    32    33    34    35    36
# 13 Jul-05        A    37    38    39    40    41    42
# 15 Aug-05        A    43    44    45    46    47    48
# 17 Sep-05        A    49    50    51    52    53    54
# 19 Oct-05        A    55    56    57    58    59    60
# 21 Nov-05        A    61    62    63    64    65    66
# 23 Dec-05        A    67    68    69    70    71    72
# 2  Jan-05        B    32    32    32    32    32    32
# 4  Feb-05        B    32    32    32    32    32    32
# 6  Mar-05        B    32    32    32    32    32    32
# 8  Apr-05        B    32    32    32    32    32    32
# 10 May-05        B    32    32    32    32    32    32
# 12 Jun-05        B    32    32    32    32    32    32
# 14 Jul-05        B    32    32    32    32    32    32
# 16 Aug-05        B    32    32    32    32    32    32
# 18 Sep-05        B    32    32    32    32    32    32
# 20 Oct-05        B    32    32    32    32    32    32
# 22 Nov-05        B    32    32    32    32    32    32
# 24 Dec-05        B    32    32    32    32    32    32
person Pierre L    schedule 24.02.2016
comment
Спасибо за ваш ответ, но я хочу изменить его так, чтобы значения компании A для каждого показателя с января 2005 года по декабрь 2005 года были на первом месте, чем те же значения для компании B. Это действительно близко к моему желаемому результату. - person ; 24.02.2016
comment
Это просто своего рода конец. Пример - тяжелая работа. - person Pierre L; 24.02.2016
comment
Не могли бы вы рассказать мне, как это отсортировать, я был бы очень признателен. - person ; 24.02.2016
comment
Если вы добавите dput(head(mydata)), где mydata - это имя вашего data.frame, я могу увидеть структуру ваших переменных - person Pierre L; 24.02.2016
comment
Я добавил сорт к ответу. - person Pierre L; 24.02.2016
comment
Спасибо за обновление, но, несмотря на то, что была создана такая же серия, это сначала A, чем B, но я не знаю, почему месяцы расположены в алфавитном порядке, например, апрель, август и так далее. - person ; 24.02.2016
comment
Как я и просил, важна внутренняя структура ваших свиданий. Если у вас есть символ или факторы, вам придется преобразовать их в формат даты. - person Pierre L; 24.02.2016
comment
Я вижу, это проблема, когда я записываю фрейм данных в csv, а затем импортирую его обратно в r, формат данных всегда меняется на фактор. - person Aquarius; 24.02.2016
comment
Я добавил конверсию для вас. Он будет работать как для factor, так и для character - person Pierre L; 24.02.2016
comment
Я получаю ошибку Error in format.default(structure(as.character(x), names = names(x), dim = dim(x), : invalid 'trim' argument - person ; 24.02.2016
comment
Я хотел бы, чтобы вы понимали, насколько важно добавить часть ваших реальных данных. Я попрошу еще раз, пожалуйста, с вишенкой на вершине, помогите мне помочь вам. Добавьте dput(head(mydf)) к своему вопросу. Передо мной нет ваших данных. Все, что у меня есть, - это ваш пример и объяснение. - person Pierre L; 24.02.2016
comment
Если ваши данные слишком велики, добавьте dput(mydata[1:10, 1:5]), чтобы получить меньший набор. - person Pierre L; 24.02.2016
comment
Я добавил некоторую часть исходного набора данных. Благодарю за терпение. - person ; 24.02.2016
comment
В вашем примере нет столбцов A или B, поэтому я не могу использовать его для панелей. Но на основе структуры приведенное выше решение должно работать. Не могли бы вы подробнее рассказать об ошибке, которую вы получаете, и о том, где вы ее получаете? - person Pierre L; 24.02.2016
comment
Код идеально подходит для моего исходного набора данных, единственная проблема - это алфавитное расположение месяцев. Ошибка, о которой я говорил выше, произошла, когда вы указали код для изменения коэффициента на сегодняшний день. - person ; 24.02.2016
comment
Вы имеете в виду строку format(newdf$Month, "%b-%y")? - person Pierre L; 24.02.2016
comment
это не алфавитное расположение. Я изменил внешний вид с Jan 2005 на Jan-2005. Это просто способ добавить тире. Расположение происходит в предыдущей строке newdf[order(newdf$variable,newdf$Month),] - person Pierre L; 24.02.2016
comment
Я добавил результат, который я получаю после запуска кода newdf <- recast(df, id.var=c("Month", "Beta"), Month+variable~Beta, value.var="value") - person ; 24.02.2016
comment
Это не может быть код после этой строки. Эта строка выдала бы вывод с месяцем и «переменной» с расширением бета-версии. Вы имеете в виду, что это оригинальный код? - person Pierre L; 24.02.2016
comment
Спасибо, я получил желаемый результат. Спасибо за терпение. Надеюсь, меня не выгнали с этого сайта, поэтому в будущем я буду более адекватно объяснять мои вопросы. - person ; 24.02.2016
comment
Позвольте нам продолжить это обсуждение в чате. - person Pierre L; 24.02.2016

Использование функций из пакета {tidyr}:

df <- data.frame(Month = c(rep("Jan-05", 6), rep("Feb-05",6)),  
                 Beta = c(paste0("Beta",1:6), paste0("Beta",1:6)), 
                 A  = 1:12,  
                 B=rep(32,12))

df2 <- tidyr::gather(df, key = Company, value = val, A, B)

df3 <- tidyr::spread(data = df2, key = Beta, value = val)

##   Month Company Beta1 Beta2 Beta3 Beta4 Beta5 Beta6
##1 Feb-05       A     7     8     9    10    11    12
##2 Feb-05       B    32    32    32    32    32    32
##3 Jan-05       A     1     2     3     4     5     6
##4 Jan-05       B    32    32    32    32    32    32
person Brandon Loudermilk    schedule 24.02.2016
comment
@Faith, что именно неудобно в двухстрочном решении, использующем общедоступный пакет? Что именно неэффективно в этом подходе? Мое тестирование показывает, что время вычислений сопоставимо с принятым ответом. - person Brandon Loudermilk; 24.02.2016

Вы можете найти тот же ответ в PDF-файле Reshape, доступном в Интернете. Перейдите по этой ссылке.
https://cran.r-project.org/web/packages/reshape/reshape.pdf

https://cran.r-project.org/web/packages/reshape2/reshape2.pdf

# This is an example. 
names(airquality) <- tolower(names(airquality))
aqm <- melt(airquality, id=c("month", "day"), na.rm=TRUE)
cast(aqm, day ~ month ~ variable)
# Not only sorting there are many other possiblities. 
cast(aqm, month ~ variable, mean)
cast(aqm, month ~ . | variable, mean)
cast(aqm, month ~ variable, mean, margins=c("grand_row", "grand_col"))
cast(aqm, day ~ month, mean, subset=variable=="ozone")
cast(aqm, month ~ variable, range)
cast(aqm, month ~ variable + result_variable, range)
cast(aqm, variable ~ month ~ result_variable,range)

Если вы последуете всем примерам, то вот ваш ответ. Reshape - удобный пакет. Пусть это вам поможет.

person user3356873    schedule 24.02.2016