Заголовки столбцов dcast таблицы данных

У меня есть таблица данных вида

ID  REGION  INCOME_BAND RESIDENCY_YEARS
1   SW  Under 5,000 10-15
2   Wales   Over 70,000 1-5
3   Center  15,000-19,999   6-9
4   SE  15,000-19,999   15-19
5   North   15,000-19,999   10-15
6   North   15,000-19,999   6-9

создан

exp = data.table(
  ID = c(1,2,3,4,5,6),
  REGION=c("SW", "Wales", "Center", "SE", "North", "North"),
  INCOME_BAND = c("Under ?5,000", "Over ?70,000", "?15,000-?19,999", "?15,000-?19,999", "?15,000-?19,999","?15,000-?19,999"),
  RESIDENCY_YEARS = c("10-15","1-5","6-9","15-19","10-15", "6-9"))

Я хотел бы преобразовать это в

Пример результата любой манипуляции с таблицей данных

Мне удалось проделать большую часть работы с dcast:

exp.dcast = dcast(exp,ID~REGION+INCOME_BAND+RESIDENCY_YEARS, fun=length,
  value.var=c('REGION', 'INCOME_BAND', 'RESIDENCY_YEARS'))

Однако мне нужна помощь в создании разумных заголовков столбцов. В настоящее время у меня есть

["ID"
"REGION.1_Center_? 15,000-? 19,999_6-9"
"REGION.1_North_? 15,000-? 19,999_10-15"
"REGION.1_North_? 15,000-? 19,999_6- 9 "
" REGION.1_SE_? 15,000-? 19,999_15-19 "" REGION.1_SW_Under? 5,000_10-15 "" REGION.1_Wales_Over? 70,000_1-5 "
" INCOME_BAND.1_Center_? 15,000-? 19,999 _6-9 "
" ДОХОДНАЯ_БАНДА.1_Северная_? 15 000-? 19 999_10-15 "
" ДОХОДНАЯ_БАНДА.1_Северная_? 15 000-? 19,999_6-9 "
" ДОХОДНАЯ_БАНДА.1_SE_? 15 000-? 19,999_15- 19 "
" INCOME_BAND.1_SW_Under? 5,000_10-15 "
" INCOME_BAND.1_Wales_Over? 70,000_1-5 "
" RESIDENCY_YEARS.1_Center_? 15,000-? 19,999_6-9 "" RESIDENCY_YEARS.1_North_? 15,000 -? 19,999_10-15 "" RESIDENCY_YEARS.1_SW_? 15,000-? 19,999_6-9 "
" RESIDENCY_YEARS.1_SE_? 15,000-? 19,999_15-19 "
" RESIDENCY_YEARS.1_SW_Under? 5,000_10-15 "< br> "RESIDENCY_YEARS.1_Wales_Over? 70,000_1-5"

И я бы хотел, чтобы заголовки столбцов были

ID  SW  Wales   Center  SE  North   Under 5,000 Over 70,000 15,000-19,999   1-5 6-9 10-15   15-19

Кто-нибудь может посоветовать?


person Philip    schedule 14.09.2017    source источник


Ответы (1)


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

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

Чтобы обрабатывать все значения одинаково, нам нужно сначала melt() все столбцы значений перед изменением формы:

melt(exp, id.vars = "ID")[, dcast(.SD, ID ~ value, length)]
   ID 1-5 10-15 15-19 6-9 ?15,000-?19,999 Center North Over ?70,000 SE SW Under ?5,000 Wales
1:  1   0     1     0   0               0      0     0            0  0  1            1     0
2:  2   1     0     0   0               0      0     0            1  0  0            0     1
3:  3   0     0     0   1               1      1     0            0  0  0            0     0
4:  4   0     0     1   0               1      0     0            0  1  0            0     0
5:  5   0     1     0   0               1      0     1            0  0  0            0     0
6:  6   0     0     0   1               1      0     1            0  0  0            0     0

Теперь результат имеет 13 столбцов вместо 19, и столбцы названы по соответствующему значению в соответствии с запросом.

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

Изменить порядок столбцов после изменения формы

Функция setcolorder() меняет порядок столбцов в data.table на месте, например без копирования:

# define column order = order of values
col_order <- c("North", "Wales", "Center", "SW", "SE", "Under ?5,000", "?15,000-?19,999", "Over ?70,000", "1-5", "6-9", "10-15", "15-19")

melt(exp, id.vars = "ID")[, dcast(.SD, ID ~ value, length)][
  # reorder columns
  , setcolorder(.SD, c("ID", col_order))]
   ID North Wales Center SW SE Under ?5,000 ?15,000-?19,999 Over ?70,000 1-5 6-9 10-15 15-19
1:  1     0     0      0  1  0            1               0            0   0   0     1     0
2:  2     0     1      0  0  0            0               0            1   1   0     0     0
3:  3     0     0      1  0  0            0               1            0   0   1     0     0
4:  4     0     0      0  0  1            0               1            0   0   0     0     1
5:  5     1     0      0  0  0            0               1            0   0   0     1     0
6:  6     1     0      0  0  0            0               1            0   0   1     0     0

Теперь сначала отображаются все REGION столбцы, за которыми следуют столбцы INCOME_BAND и RESIDENCY_YEARS в указанном порядке.

Установите уровни факторов перед изменением формы

Если value преобразован в фактор с должным образом упорядоченными уровнями факторов, dcast() будет использовать уровни факторов для упорядочивания столбцов:

melt(exp, id.vars = "ID")[, value := factor(value, col_order)][
  , dcast(.SD, ID ~ value, length)]
   ID North Wales Center SW SE Under ?5,000 ?15,000-?19,999 Over ?70,000 1-5 6-9 10-15 15-19
1:  1     0     0      0  1  0            1               0            0   0   0     1     0
2:  2     0     1      0  0  0            0               0            1   1   0     0     0
3:  3     0     0      1  0  0            0               1            0   0   1     0     0
4:  4     0     0      0  0  1            0               1            0   0   0     0     1
5:  5     1     0      0  0  0            0               1            0   0   0     1     0
6:  6     1     0      0  0  0            0               1            0   0   1     0     0

Установите уровни факторов перед изменением формы - ленивая версия

Если достаточно, чтобы столбцы были сгруппированы по REGION, INCOME_BAND и RESIDENCY_YEARS, тогда мы можем использовать сокращение, чтобы не указывать каждое значение в col_order. Функция fct_inorder() из пакета forcats переупорядочивает уровни факторов по их первому появлению в векторе:

melt(exp, id.vars = "ID")[, value := factor(value, col_order)][
  , dcast(.SD, ID ~ value, length)]
   ID SW Wales Center SE North Under ?5,000 Over ?70,000 ?15,000-?19,999 10-15 1-5 6-9 15-19
1:  1  1     0      0  0     0            1            0               0     1   0   0     0
2:  2  0     1      0  0     0            0            1               0     0   1   0     0
3:  3  0     0      1  0     0            0            0               1     0   0   1     0
4:  4  0     0      0  1     0            0            0               1     0   0   0     1
5:  5  0     0      0  0     1            0            0               1     1   0   0     0
6:  6  0     0      0  0     1            0            0               1     0   0   1     0

Это работает, потому что вывод melt() упорядочен по variable:

melt(exp, id.vars = "ID")
    ID        variable           value
 1:  1          REGION              SW
 2:  2          REGION           Wales
 3:  3          REGION          Center
 4:  4          REGION              SE
 5:  5          REGION           North
 6:  6          REGION           North
 7:  1     INCOME_BAND    Under ?5,000
 8:  2     INCOME_BAND    Over ?70,000
 9:  3     INCOME_BAND ?15,000-?19,999
10:  4     INCOME_BAND ?15,000-?19,999
11:  5     INCOME_BAND ?15,000-?19,999
12:  6     INCOME_BAND ?15,000-?19,999
13:  1 RESIDENCY_YEARS           10-15
14:  2 RESIDENCY_YEARS             1-5
15:  3 RESIDENCY_YEARS             6-9
16:  4 RESIDENCY_YEARS           15-19
17:  5 RESIDENCY_YEARS           10-15
18:  6 RESIDENCY_YEARS             6-9
person Uwe    schedule 04.12.2017