Quel est l'équivalent data.table
de la commande complete
de tidyr
avec le groupe by
?
Quelle est la relation entre on
et by
pour data.table
?
Exemple:
setDT(dt)[CJ(a=a,b=b,unique=TRUE), on=.(a,b) , by = .(c)]
L'objectif est d'obtenir ce qui suit: p >
a b c 1 4 x 1 5 x 1 6 x 1 7 x 2 4 x 2 5 x 2 6 x 2 7 x 3 8 y 3 9 y 3 10 y 3 11 y 4 8 y 4 9 y 4 10 y 4 11 y
donc quelque chose à peu près comme ceci:
dt=data.table(a = c(1,1,2,2,3,3,4,4) , b = c(4,5,6,7,8,9,10,11) , c = c("x","x","x","x","y","y","y","y")) show(dt) a b c 1: 1 4 x 2: 1 5 x 3: 2 6 x 4: 2 7 x 5: 3 8 y 6: 3 9 y 7: 4 10 y 8: 4 11 y
mais cela ne fonctionne pas et le code data.table > la documentation est mince sur cet aspect de la syntaxe.
Solutions insuffisantes:
Les articles SO suivants abordent des problèmes similaires, mais ne fournissent pas de solutions suffisantes dans ce contexte.
3 Réponses :
Essayez ceci:
c a b 1: x 1 4 2: x 1 5 3: x 1 6 4: x 1 7 5: x 2 4 6: x 2 5 7: x 2 6 8: x 2 7 9: y 3 8 10: y 3 9 11: y 3 10 12: y 3 11 13: y 4 8 14: y 4 9 15: y 4 10 16: y 4 11
donnant:
dt[, CJ(a = a, b = b, unique = TRUE), by = "c"]
Pourquoi on
n'est-il plus nécessaire?
on
est utilisé pour faire une fusion mais il n'y a pas de fusion ici.
dans le jeu de données réel, j'ai perdu toutes les colonnes supplémentaires. ma faute,. je vais mettre à jour l'exemple
Dans ce cas, effectuez une fusion par la suite.
Ce qui suit renverra le résultat souhaité.
library(data.table) dt=data.table(a = c(1,1,2,2,3,3,4,4) , b = c(4,5,6,7,8,9,10,11) , c = c("x","x","x","x","y","y","y","y")) dttrue <- fread('a b c 1 4 x 1 5 x 1 6 x 1 7 x 2 4 x 2 5 x 2 6 x 2 7 x 3 8 y 3 9 y 3 10 y 3 11 y 4 8 y 4 9 y 4 10 y 4 11 y') dt2 <- dt[,CJ(a=a,b=b,unique = TRUE),by = c] all.equal(dt2[,.(a,b,c)], dttrue) #true
complete
conserve d'autres colonnes non liées, je vais donc en ajouter une ...
library(dplyr); library(tidyr) data.frame(dt) %>% group_by(c) %>% complete(a, b) # A tibble: 16 x 4 # Groups: c [2] c a b d <chr> <dbl> <dbl> <chr> 1 x 1 4 K 2 x 1 5 L 3 x 1 6 <NA> 4 x 1 7 <NA> 5 x 2 4 <NA> 6 x 2 5 <NA> 7 x 2 6 M 8 x 2 7 N 9 y 3 8 O 10 y 3 9 P 11 y 3 10 <NA> 12 y 3 11 <NA> 13 y 4 8 <NA> 14 y 4 9 <NA> 15 y 4 10 Q 16 y 4 11 R
Pour compléter les combos axb pour chaque c, je ferais un nouveau table avec ces combos (exactement comme déjà dans la réponse de @ G.Grothendieck) et update-join pour obtenir d et d'autres colonnes non combo:
dt[, .SD[CJ(a = a, b = b, unique = TRUE), on = .(a, b)], by = c]
Alternativement, vous pouvez faire un jointure interne (?), bien que cela soit inefficace car cela crée deux nouvelles tables:
dt[mDT, on=cvars] # or more concisely.... dt[dt[, CJ(a = a, b = b, unique=TRUE), by=c], on=.(a,b,c)]
Ou, faites une jointure interne par groupe by =
( de @eddi):
mDT = dt[, CJ(a = a, b = b, unique=TRUE), by=c] cvars = copy(names(mDT)) ovars = setdiff(names(dt), cvars) mDT[, (ovars) := dt[.SD, on=cvars, mget(sprintf("x.%s", ovars))]] setcolorder(mDT, names(dt)) a b c d 1: 1 4 x K 2: 1 5 x L 3: 1 6 x <NA> 4: 1 7 x <NA> 5: 2 4 x <NA> 6: 2 5 x <NA> 7: 2 6 x M 8: 2 7 x N 9: 3 8 y O 10: 3 9 y P 11: 3 10 y <NA> 12: 3 11 y <NA> 13: 4 8 y <NA> 14: 4 9 y <NA> 15: 4 10 y Q 16: 4 11 y R
Pour comparaison dans le tidyverse:
library(data.table) dt = data.table( a = c(1,1,2,2,3,3,4,4) , b = c(4,5,6,7,8,9,10,11) , c = c("x","x","x","x","y","y","y","y"), d = LETTERS[10 + 1:8]) a b c d 1: 1 4 x K 2: 1 5 x L 3: 2 6 x M 4: 2 7 x N 5: 3 8 y O 6: 3 9 y P 7: 4 10 y Q 8: 4 11 y R
Je ferais dt [ .SD [CJ (a = a, b = b, unique = TRUE), on =. (A, b)], by = c]
s'il n'y a pas ' t trop de valeurs c
.