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 .