Я хочу отсортировать наблюдения по квартилям по переменной "varbl". Поскольку мои данные довольно большие (2 ГБ), я пытаюсь реализовать их через data.table. Проблема в том, что мне нужно использовать внешние квартильные разрывы, которые зависят от группы. Групповая переменная — «prd» или «prd1».
Мои данные и точки останова следующие:
data <- data.table(id = c(1,2,3,4,5,1,2,3,4,5), prd1 = c(1,1,1,1,1,2,2,2,2,2), varbl = c(-1.6, -0.7, 0.1, 1.2, -0.5, -0.8, 0.4, 1.2, 1.9, 4))
bks <- data.table(prd=c(1,2), br0 = c(-5,-5), br1=c(-1,0), br2=c(0, 0.5), br3=c(1, 3), br4=c(5,5))
> data
id prd1 varbl
1: 1 1 -1.6
2: 2 1 -0.7
3: 3 1 0.1
4: 4 1 1.2
5: 5 1 -0.5
6: 1 2 -0.8
7: 2 2 0.4
8: 3 2 1.2
9: 4 2 1.9
10: 5 2 4.0
> bks
prd br0 br1 br2 br3 br4
1: 1 -5 -1 0.0 1 5
2: 2 -5 0 0.5 3 5
Желаемый результат:
> output
id prd1 varbl ntile
1: 1 1 -1.6 1
2: 2 1 -0.7 2
3: 3 1 0.1 3
4: 4 1 1.2 4
5: 5 1 -0.5 2
6: 1 2 -0.8 1
7: 2 2 0.4 2
8: 3 2 1.2 3
9: 4 2 1.9 3
10: 5 2 4.0 4
Я попробовал следующий код, но он не работает, так как я не могу подмножить bks на том же prd, что и текущий prd1 из данных:
data[, ntile := cut(varbl, breaks = bks[prd==prd1], include.lowest=TRUE, labels = 1:4)]
В качестве еще одной попытки я попытался сначала объединить данные и bks (я бы предпочел этого не делать, поскольку это увеличит размер данных с 2 ГБ до 4 ГБ). а затем отсортировать наблюдения по квантилям. Это не удается, так как я не могу понять, как использовать имена столбцов для построения вектора точек останова для каждой строки. Ни одна из попыток не сработала.
setnames(data, "prd1", "prd")
data <- data[bks, on = "prd", nomatch=0]
data[, ntile := cut(varbl, breaks = .(br0, br1, br2, br3, br4), include.lowest=TRUE, labels=1:4)]
data[, ntile := cut(varbl, breaks = colnames(bks)[-1], include.lowest=TRUE, labels=1:4)]
data[, ntile := cut(varbl, breaks = c("br0", "br1", "br2", "br3", "br4"), include.lowest=TRUE, labels=1:4)]
Нет, я не против. Как это сделать с неэквивалентным соединением?
Небольшая перестановка bks
означает, что вы можете сделать это как объединение:
bks <- bks[, data.frame(embed(unlist(.SD),2)[,2:1]), by=prd]
bks[, grp := seq_len(.N), by=prd]
# prd X1 X2 grp
#1: 1 -5.0 -1.0 1
#2: 1 -1.0 0.0 2
#3: 1 0.0 1.0 3
#4: 1 1.0 5.0 4
#5: 2 -5.0 0.0 1
#6: 2 0.0 0.5 2
#7: 2 0.5 3.0 3
#8: 2 3.0 5.0 4
data[bks, on=c("prd1" = "prd","varbl>=X1","varbl<X2"), grp := i.grp]
# id prd1 varbl grp
# 1: 1 1 -1.6 1
# 2: 2 1 -0.7 2
# 3: 3 1 0.1 3
# 4: 4 1 1.2 4
# 5: 5 1 -0.5 2
# 6: 1 2 -0.8 1
# 7: 2 2 0.4 2
# 8: 3 2 1.2 3
# 9: 4 2 1.9 3
#10: 5 2 4.0 4
Не возражаете, если
bks
немного переставить? Если это так, то это может быть прямое неэквивалентное соединение.