Сортировщик квартилей с заданными извне точками останова в R data.table - PullRequest
2 голосов
/ 29 мая 2019

Я хочу отсортировать наблюдения в квартили по переменной "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)]

1 Ответ

3 голосов
/ 29 мая 2019

Перестановка 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
...