Очень хорошо написанный вопрос.
Я вижу, вы сделали пример, основанный на ?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.
Надеюсь, чтопомогает, удачи!