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_idpour toutes les valeurs deGroup? DoncGroup = 1aurait la même valeur dedt_unit?Non, je veux des valeurs aléatoires à chaque fois.