Куб данных R определяет иерархию - PullRequest
0 голосов
/ 15 октября 2018

У меня есть некоторые проблемы с пакетом OLapCube, data.cube:

install.packages("data.cube", repos = paste0("https://", c(
    "jangorecki.gitlab.io/data.cube",
    "cloud.r-project.org"
)))

Некоторые тестовые данные:

 library(data.table)
 set.seed(42)

 dt <- CJ(color = c("green","yellow","red"),
            year = 2011:2015,
            month = 1:12,
            status = c("active","inactive","archived","removed")
 )[sample(600)]

 dt[, "value" := sample(4:7/2, nrow(dt), TRUE)]

Теперь я хотел бы создать куб и применить иерархиюпо временным измерениям.Примерно так:

library(data.cube)
dc <- as.data.cube(dt, id.vars = c("color", "year", "month", "status"), 
                   measure.vars = "value", 
                   hierarchies = list(time <- list("year, month")))

Если я запускаю этот код, я получаю ошибку:

Error in as.data.cube.data.table(dt, id.vars = c("color", "year", "month",  : 
  identical(names(hierarchies), id.vars) | identical(names(hierarchies),  .... is not TRUE

Если я пытаюсь что-то вроде

hierarchies = list(time <- list("year, month"), color <- list("color"), 
                  status <- list("status"))

, я получаю то же самоеошибка.

1 Ответ

0 голосов
/ 15 октября 2018

Очень хорошо написанный вопрос.
Я вижу, вы сделали пример, основанный на ?as.data.cube примерах, поэтому я попытаюсь ответить на ваш вопрос, используя эти примеры тоже

# Original example goes as follows
library(data.cube)
library(data.table)
set.seed(1L)
dt = CJ(color = c("green","yellow","red"),
        year = 2011:2015,
        status = c("active","inactive","archived","removed"))[sample(30)]
dt[, "value" := sample(4:7/2, nrow(dt), TRUE)]

dc = as.data.cube(
  x = dt, id.vars = c("color","year","status"),
  measure.vars = "value",
  hierarchies = sapply(c("color","year","status"),
                       function(x) list(setNames(list(character()), x)),
                       simplify=FALSE)
)
str(dc)

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

sapply(c("color","year","status"),
       function(x) list(setNames(list(character()), x)),
       simplify=FALSE) -> h
str(h)
#List of 3
# $ color :List of 1
#  ..$ :List of 1
#  .. ..$ color: chr(0) 
# $ year  :List of 1
#  ..$ :List of 1
#  .. ..$ year: chr(0) 
# $ status:List of 1
#  ..$ :List of 1
#  .. ..$ status: chr(0)     

hierarchies = list(time <- list("year, month"), color <- list("color"), 
                   status <- list("status"))
str(hierarchies)
#List of 3
# $ :List of 1
#  ..$ : chr "year, month"
# $ :List of 1
#  ..$ : chr "color"
# $ :List of 1
#  ..$ : chr "status"

Мы видим, что иерархии в руководстве - это список именованных элементов, а ваш пример - список неназванных элементов.
Я полагал, что вы неправильно использовали <-, где = должно бытьиспользуемый.<- не всегда равен = оператору.Подробнее о таком случае вы можете прочитать в 3.1.3.1 Назначение <- против =.

Итак, давайте посмотрим, достаточно ли исправления

hierarchies = list(time = list(c("year, month")), color = list("color"), 
                   status = list("status"))

dc <- as.data.cube(dt, id.vars = c("color", "year", "month", "status"), 
                   measure.vars = "value", 
                   hierarchies = hierarchies)

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

"year, month"

должно быть записано как

c("year","month")

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

library(data.table)
set.seed(42)

dt <- CJ(color = c("green","yellow","red"),
         year = 2011:2015,
         month = 1:12,
         status = c("active","inactive","archived","removed")
)[sample(600)
  ][, yearmonth:=sprintf("%04d%02d", year, month) # this ensure four numbers for year and 2 numbers for month
    ]

dt[, "value" := sample(4:7/2, nrow(dt), TRUE)]

Теперь давайте создадим иерархии, отметим, что year был изменен на yearmonth.В приведенных ниже иерархиях вектор значений c("year","month") означает, что эти атрибуты зависят от yearmonth.Пожалуйста, смотрите больше примеров в ?as.data.cube для более сложных случаев иерархий.

hierarchies = list(
  color = list(color = list(color = character())),
  yearmonth = list(yearmonth = list(yearmonth = c("year","month"))),
  status = list(status = list(status = character()))
)

dc = as.data.cube(
  x = dt, id.vars = c("color","yearmonth","status"),
  measure.vars = "value",
  hierarchies = hierarchies
)
str(dc)

Наш data.cube был успешно создан.Попробуем запросить его, используя ключ yearmonth

dc[, .(yearmonth=201105L)] -> d
as.data.table(d)
dc[, .(yearmonth=201105L), drop=FALSE] -> d
as.data.table(d)

Теперь попробуйте запросить его, используя атрибуты измерения, год и месяц, и оба

dc[, .(year=2011L)] -> d
as.data.table(d) # note that dimension is not being dropped because it still have more than 1 value
dc[, .(month=5L)] -> d
as.data.table(d)
dc[, .(year=2011L, month=5L)] -> d
as.data.table(d) # here dimension has been dropped because there was only single element in that dimension, you can of course use `drop=FALSE` if needed.

Надеюсь, чтопомогает, удачи!

...