J'ai deux tables de données dt_main
et dt_unit
.
dt_main[,Unit:=sample(dt_unit[Group==Group]$Unit_id,size=1)]
dt_main
ressemblent à ceci: p>
> dt_unit[Group==1] Group Unit_id 1: 1 2624 2: 1 2963 3: 1 1974 4: 1 1800 5: 1 1930 6: 1 1325
dt_unit
ressemble à ceci:
> dt_unit Group Unit_id 1: 1 2624 2: 1 2963 3: 1 1974 4: 1 1800 5: 2 1851 6: 1 1930 7: 1 1325 8: 2 1329 9: 2 1553 10: 2 2445
Je voudrais remplir le Colonne Unit
dans dt_main
en échantillonnant un Unit_id
de dt_unit
à dt_main
avec le même Group
.
Par exemple, pour la première ligne de dt_main
(donc Group
= 1), le code doit rechercher dt_unit
et recherchez les lignes où Group
vaut 1 (voir ci-dessous), puis sélectionnez un Unit_id
et insérez-le dans Unit
.
> dt_main ID Group Unit 1: 4 1 0 2: 7 1 0 3: 1 1 0 4: 2 2 0 5: 13 2 0 6: 19 2 0 7: 11 2 0 8: 17 3 0 9: 14 1 0 10: 3 3 0
J'ai essayé quelque chose comme ça qui attribuait le même numéro à chaque ligne:
set.seed(1) dt_main<-data.table(ID=sample(1:20,size=10),Group=sample(1:3,size=10,replace=TRUE),Unit=0) dt_unit<-data.table(Group=sample(1:3,size=10,replace=TRUE),Unit_id=sample(1000:3000,size=10,replace=TRUE))
J'ai aussi essayé sapply
mais pas bon.
4 Réponses :
try:
sample_unit_id <- function(group) {sapply(group,function(g){sample(dt_unit[Group==g,Unit_id],1)})} dt_main[,.(Group,Unit_id = sample_unit_id(Group))] Group Unit_id 1: 3 2831 2: 3 2133 3: 2 2814 4: 2 2814 5: 2 1464 6: 2 2752 7: 1 1832 8: 2 1464 9: 2 2814 10: 2 2752
Comment avez-vous obtenu les valeurs de Group = 3
? Il n'y a pas de Group = 3
dans le bloc de données dt_unit
...
Regardez la source, c'est un dataframe généré aléatoirement
Quelque chose cloche ici. Pourriez-vous essayer de vérifier avec seed = 1
OK, j'ai oublié la graine :-)
Voici une solution de base R où nous faisons correspondre les groupes et échantillonnons 1 valeur à chaque fois,
dt_main$Unit <- sapply(dt_main$Group, function(i) { v1 <- dt_unit$Unit_id[dt_unit$Group %in% i]; if (length(v1) > 0) {sample(v1, 1) } else {NA} }) # ID Group Unit # 1: 4 1 1930 # 2: 7 1 1325 # 3: 1 1 1325 # 4: 2 2 1329 # 5: 13 2 2445 # 6: 19 2 2445 # 7: 11 2 1851 # 8: 17 3 NA # 9: 14 1 1930 #10: 3 3 NA
Je sais que cela change la question, mais y a-t-il une solution simple pour ce qui suit: Je veux ajouter une deuxième condition tout en recherchant la valeur. Par exemple, supposons qu'il y ait également une colonne Size
dans chaque table et lorsque je recherche la deuxième table de données, je veux échantillonner à partir des lignes dont: la colonne Group
correspond et dt_main $ Size> dt_unit $ Size
.
Cela devrait être une solution facile. Une façon vous vient à l'esprit, vous pouvez ajouter un v2
sous v1
dans la fonction sapply ()
qui n'obtiendra que les unit_ids de ceux qui satisfont votre état. Ensuite, intersectez
v1 et v2 et échantillonnez comme d'habitude
Vous pouvez joindre dt_main
et dt_unit
par Group
et sélectionner une ligne aléatoire pour chaque ID
.
En utilisant dplyr
, vous pouvez le faire en:
library(dplyr) left_join(dt_main, dt_unit, by = 'Group') %>% group_by(ID) %>% sample_n(1) # ID Group Unit_id # <int> <int> <int> # 1 1 1 1800 # 2 2 2 2445 # 3 3 3 NA # 4 4 1 2963 # 5 7 1 1800 # 6 11 2 1851 # 7 13 2 1553 # 8 14 1 1325 # 9 17 3 NA #10 19 2 2445
J'ai supprimé la colonne Unit
de data.table
création.
Une autre réponse avec mapply
, que j'ai utilisée pour le cas avec plusieurs conditions. Dans ce cas, en recherchant je vérifie si les colonnes du Groupe
correspondent ET qu'une nouvelle colonne ( Size
) dans dt_main est plus grande que celle de dt_unit
. En tant qu'OP, j'ai dû ajouter une autre condition au message d'origine et donc ajouter cette solution pour aider les futurs utilisateurs.
my_fun<-function(var1,var2) { d<-dt_unit[(Group%in%var1)&(Size>=var2)] if(nrow(d)>=2){ sample(x=d$Unit_id,size=1,replace=T) }else {d$Unit_id} } vars1<-dt_main$Group vars2<-dt_main$Size dt_main$Unit<-mapply(my_fun,vars1,vars2)
Voulez-vous le même
Unit_id
pour toutes les valeurs deGroup
? DoncGroup = 1
aurait la même valeur dedt_unit
?Non, je veux des valeurs aléatoires à chaque fois.