Расчет группового процента, есть ли лучший способ - PullRequest
1 голос
/ 22 марта 2019

У меня есть данные с 3 категориальными переменными: primarydx, NumDx и ContractType.

primarydx <- rep(c("AB","MT"),10)
NumDx <- rep(c(1,2,3), length.out=20 )
ContractType <- rep( c("W","L","W","W","W") , length.out=20)
SecDx3 <- data.table(primarydx, NumDx, ContractType)

Я хочу рассчитать процент записей каждого ContractType в пределах primarydx и NumDx. Работает следующий код:

Num <-SecDx3[ , .(n=.N), by=.(primarydx, NumDx, ContractType)]
denom <- SecDx3[ , .(d=.N), by=.(primarydx, NumDx)]
pct <- merge(Num,denom)
pct[,pct:=n/d][]

Есть ли лучший способ?

Я нашел что-то вроде:

SecDx3[,{
  d =.N
  .SD[, .(pct = .N/d), by=.(primarydx, NumDx, ContractType)]
  }, by=.(primarydx, NumDx)]

, но это возвращает ошибку "Элементы в списке 'by' или 'keyby' имеют длину (1,1,20). Длина каждого элемента должна быть одинаковой с количеством строк в x или количеством строк, возвращаемых i (20) «. чего я не понимаю.

Спасибо за вашу помощь,

David

Ответы [ 3 ]

1 голос
/ 25 марта 2019

Вероятно, быстрее будет

SecDx3[, d:=.N, by=.(primarydx, NumDx)
       ][, {
           n<-.N
           .(n=n, d=d[1L], pct=n/d[1L])
         },
         by=.(primarydx, NumDx, ContractType)]
0 голосов
/ 25 марта 2019

Следуя изложенному выше подходу Фрэнка, поскольку числитель и знаменатель на самом деле не нужны, следующий код кажется компактным и понятным:

SecDx3[, .N, by=.(ContractType, primarydx, NumDx)
       ][, .(pct = N/sum(N)), by=.(primarydx, NumDx)]
0 голосов
/ 24 марта 2019

Похоже, вы были близки со своим вторым фрагментом кода, но кажется, что вы можете использовать каждый столбец только один раз за by с.Я нашел это работает:

SecDx3[, {n <- .N; .SD[, list(pct = .N / n), by = .(ContractType)]}, by = .(primarydx, NumDx)]

    primarydx NumDx ContractType       pct
 1:        AB     1            W 0.7500000
 2:        AB     1            L 0.2500000
 3:        MT     2            L 0.2500000
 4:        MT     2            W 0.7500000
 5:        AB     3            W 1.0000000
 6:        MT     1            W 1.0000000
 7:        AB     2            W 0.6666667
 8:        AB     2            L 0.3333333
 9:        MT     3            W 0.6666667
10:        MT     3            L 0.3333333
...