2017-07-13 2 views
1

Je souhaite subdiviser mon fichier data.table en procédant comme suit: en regroupant id et group, prenez la 1ère rangée de la rangée lorsque la condition est remplie. Cela signifie que si la condition est remplie au 3ème rang, je voudrais garder les lignes 1,2 et 3.Sous-ensemble jusqu'à ce que la condition soit remplie (y compris) par le groupe de données data.table

Exemple de données:

id time group 
1: 1 0  1 
2: 1 20  1 
3: 1 0  2 
4: 1 40  2 
5: 2 0  1 
6: 2 35  1 
7: 2 50  1 
8: 3 0  1 
9: 3 10  1 
10: 3 20  1 
11: 3 0  2 
12: 3 25  2 
13: 3 45  2 

La condition est: time > 30 donc attendus les résultats seront:

id time group 
1: 1 0  2 
2: 1 40  2 
3: 2 0  1 
4: 2 35  1 
5: 3 0  2 
6: 3 25  2 
7: 3 45  2 

J'ai essayé: df[1:which(time >30)[1], .SD, by = .(id, group)]

mais il retourne:

id group time 
1: 1  1 0 
2: 1  1 20 
3: 1  2 0 
4: 1  2 40 

données:

structure(list(id = c(1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3), 
       time = c(0, 20, 0, 40, 0, 35, 50, 0, 10, 20, 0, 25, 45), 
       group = c(1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2)), .Names = c("id", 
                      "time", "group"), row.names = c(NA, -13L), class = c("data.table", 
                                    "data.frame")) 

MISE À JOUR montrant un comportement attendu de la réponse de akrun avec un autre jeu de données:

données:

> dftest 
    patientid groupe arret dateConsult lag_dateConsult temps abst temps_cum 
1: 0303H233457  2  1 2011-10-05   <NA>  0 1   0 
2: 0303H233457  2  1 2011-11-09  2011-10-05 35 1  35 
3: 0303H233457  2  1 2011-12-21  2011-11-09 42 1  77 
4: 0303H233457  2  1 2012-01-30  2011-12-21 40 1  117 
5: 0303H233457  2  1 2012-04-18  2012-01-30 79 1  196 
6: 0303H233457  2  1 2012-08-27  2012-04-18 131 1  327 
7: 0303H233457  4  1 2012-11-19   <NA>  0 1   0 
8: 0303H233457  4  1 2013-01-07  2012-11-19 49 1  49 

Ce que je reçois:

> dftest[dftest[, .I[seq(which(temps_cum > 30))], .(patientid, groupe)]$V1] 
    patientid groupe arret dateConsult lag_dateConsult temps abst temps_cum 
1: 0303H233457  2  1 2011-10-05   <NA>  0 1   0 
2: 0303H233457  2  1 2011-11-09  2011-10-05 35 1  35 
3: 0303H233457  2  1 2011-12-21  2011-11-09 42 1  77 
4: 0303H233457  2  1 2012-01-30  2011-12-21 40 1  117 
5: 0303H233457  2  1 2012-04-18  2012-01-30 79 1  196 
6: 0303H233457  4  1 2012-11-19   <NA>  0 1   0 
7: 0303H233457  4  1 2013-01-07  2012-11-19 49 1  49 

Résultats attendus:

 patientid groupe arret dateConsult lag_dateConsult temps abst temps_cum 
1: 0303H233457  2  1 2011-10-05   <NA>  0 1   0 
2: 0303H233457  2  1 2011-11-09  2011-10-05 35 1  35 
3: 0303H233457  4  1 2012-11-19   <NA>  0 1   0 
4: 0303H233457  4  1 2013-01-07  2012-11-19 49 1  49 

données:

structure(list(patientid = c("0303H233457", "0303H233457", "0303H233457", 
          "0303H233457", "0303H233457", "0303H233457", "0303H233457", "0303H233457" 
), groupe = c(2, 2, 2, 2, 2, 2, 4, 4), arret = c(1, 1, 1, 1, 
               1, 1, 1, 1), dateConsult = structure(c(15252, 15287, 15329, 15369, 
                         15448, 15579, 15663, 15712), class = "Date"), lag_dateConsult = structure(c(NA, 
                                            15252, 15287, 15329, 15369, 15448, NA, 15663), class = "Date"), 
temps = c(0, 35, 42, 40, 79, 131, 0, 49), abst = c(1, 1, 
                1, 1, 1, 1, 1, 1), temps_cum = c(0, 35, 77, 117, 196, 327, 
                        0, 49)), .Names = c("patientid", "groupe", "arret", "dateConsult", 
                             "lag_dateConsult", "temps", "abst", "temps_cum"), class = c("data.table", 
                                            "data.frame"), row.names = c(NA, -8L)) 
+0

Si vous vouliez dire 'dftest [dftest [, .Je [seq (qui (temps_cum> 30) [1])],. (patientid, groupe)] $ V1]' cela fonctionne pour moi – akrun

+0

@akrun Ouais c'est ce à quoi je m'attendais. Cependant j'ai eu cette erreur sur mon ensemble de données complet: 'Erreur dans seq.default (qui (temps_cum> 30) [1]): 'de' ne peut pas être NA, NaN ou infini', pensez-vous ce que cela peut causer? –

+0

S'il vous plaît vérifiez s'il n'y a qu'un seul élément par groupe et que celui-ci ne se qualifie pas pour 'temps_cum> 30', dans ce cas, peut-être, vous pouvez utiliser une condition' if/else' 'dftest [, if (any (temps_cum > 30)) .I [seq (qui (temps_cum> 30) [1])],. (Patientid, groupe)] ' – akrun

Répondre

1

Après regroupement par 'id', 'groupe', obtenir l'index de la ligne où le 'temps' est supérieur à 30, et sous-ensemble des lignes

df1[df1[, .I[seq(which(time > 30))], .(id, group)]$V1] 

Si nous avons aussi besoin jusqu'à la dernière ligne où le « temps » est gr mangeur de 30

df1[df1[, .I[seq(tail(which(time > 30), 1))], .(id, group)]$V1] 
# id time group 
#1: 1 0  2 
#2: 1 40  2 
#3: 2 0  1 
#4: 2 35  1 
#5: 2 50  1 
#6: 3 0  2 
#7: 3 25  2 
#8: 3 45  2 
+1

fonctionne comme un charme comme toujours, je vais accepter la réponse dès que possible –

+0

Désolé de vous déranger à nouveau, mais j'ai un comportement étrange avec mes données réelles et les résultats ne sont pas attendus, il sera possible que vous vérifiez avec un sous-ensemble sur lequel ne fonctionne pas comme prévu? –

+0

@MbrMbr Pourriez-vous s'il vous plaît mettre à jour votre poste avec un petit exemple qui montre les bugs – akrun