2
votes

Comment attribuer des valeurs séquentielles à une variable dans R tout en définissant la séquence par le nombre de valeurs contenues dans une variable différente

J'ai des données patient où un patient a reçu la même évaluation à différents moments. Je souhaite numéroter ces évaluations de manière séquentielle par date.

Voici ma contribution:

12 x 3 df avec cols: pt_id, Assess_date, Assess_id

Voici le résultat souhaité:

12 x 5 df avec cols: pt_id, evalu_date, evalu_id, num_assess, evalu_num

Voici ce que j'ai essayé:

data <- data %>% 
           group_by(pt_id) %>%
           mutate(num_assess <- n_distinct(assess_date))

data$assess_num <- NA

data <- data %>% 
           group_by(pt_id) %>% 
           for(i in 1:num_assess) {
              assess_num <- i
            }

J'ai également essayé d'utiliser n_distinct pour définir la séquence sans créer la variable evalu_num, mais cela n'a pas fonctionné non plus

Voici l'erreur que j'obtiens:

Erreur dans for (. in i) 1: num_assess: 4 arguments passés à 'pour' ce qui nécessite 3

Pensées? TIA!


2 commentaires

Hé tws061105, merci d'avoir publié ce que vous avez tenté. Il est également conseillé de publier un exemple reproductible . Sur cette note, est-ce que Assess_date est une date ou une chaîne? Si c'est le cas, vous pouvez extraire le mois avec quelque chose comme: as.numeric (format (x, "% m")) (en supposant que vous vouliez qu'il soit numérique).


Hey Andrew - merci pour cette suggestion! Cela a vraiment du sens! Je garderai cela à l'esprit pour les prochains articles!


3 Réponses :


1
votes

Voici une version simplifiée utilisant vos dates (comme facteurs) pour extraire simplement le niveau de chaque variable:

library(tidyr)
library(dplyr)

# data.example as tibble:
data.example = structure(list(pt_id = c(1234L, 1234L, 1234L, 1234L, 4567L, 4567L, 
  4567L, 4567L, 8900L, 8900L, 8900L, 8900L), assess_date = structure(c(1L, 
  2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("1/1/2019", 
  "1/2/2019", "1/3/2019", "1/4/2019"), class = "factor"), assess_id = c(64L, 
  64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L)), row.names = c(NA, 
  -12L), class = c("tbl_df", "tbl", "data.frame"))

# if assess_date is the string class:
data.example <- data.example %>% 
  group_by(pt_id) %>%
  mutate(assess_num = as.integer(as.factor(assess_date)))

# if assess_date is the factor class:
data.example <- data.example %>% 
  group_by(pt_id) %>%
  mutate(assess_num = as.integer(as.factor(as.Date(assess_date,"%m/%d/%Y"))))

# if assess_date is the Date class:
data.example <- data.example %>% 
  group_by(pt_id) %>%
  mutate(assess_num = as.integer(as.factor(assess_date)))

Si ce ne sont pas (encore) des facteurs, alors: p >

# A tibble: 12 x 4
# Groups:   pt_id [3]
   pt_id assess_date assess_id assess_num
   <int> <fct>           <int>      <int>
 1  1234 1/1/2019           64          1
 2  1234 1/2/2019           64          2
 3  1234 1/3/2019           64          3
 4  1234 1/4/2019           64          4
 5  4567 1/1/2019           64          1
 6  4567 1/2/2019           64          2
 7  4567 1/3/2019           64          3
 8  4567 1/4/2019           64          4
 9  8900 1/1/2019           64          1
10  8900 1/2/2019           64          2
11  8900 1/3/2019           64          3
12  8900 1/4/2019           64          4

Le résultat ressemble à:

data.example <- data.example %>% 
  group_by(pt_id) %>%
  mutate(assess_num = as.integer(as.factor(assess_date)))

MODIFIER: Voici un ensemble plus explicite de solutions potentielles en fonction de la classe de colonne d'origine access_date :

data.example = structure(list(pt_id = c(1234L, 1234L, 1234L, 1234L, 4567L, 4567L, 
                  4567L, 4567L, 8900L, 8900L, 8900L, 8900L), assess_date = structure(c(1L, 
                  2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("1/1/2019", 
                  "1/2/2019", "1/3/2019", "1/4/2019"), class = "factor"), assess_id = c(64L, 
                  64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L)), class = "data.frame", row.names = c(NA, 
                  -12L))

data.example <- data.example %>% 
  group_by(pt_id) %>%
  mutate(assess_num = as.integer(assess_date))


4 commentaires

@ tws061105, le L indique que la valeur sera un entier . Vous pouvez créer les données reproductibles en prenant tout ou partie de vos données d'exemple et en utilisant dput (par exemple dput (mtcars) ).


En fait, cela ne fonctionne pas vraiment. Cela a fonctionné lorsque je viens d'exécuter la solution proposée, mais lorsque je l'applique à mes données réelles, cela ne fonctionne pas tout à fait. Je vois que cette solution proposée établit le "niveau" de la date d'évaluation comme assess_date = structure (c (1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), puis les étiquettes ceux avec les dates de ces évaluations, mais dans mes données réelles, je ne peux pas facilement convertir les dates en un entier, et la conversion de la colonne entière en un facteur ne fonctionne pas non plus, car les patients peuvent être évalués à des jours différents ( il n'y a pas une seule série de dates d'évaluation)


Merci pour l'aide et avec votre patience avec moi pour publier une version simplifiée de mes données qui est loin d'être idéale et non reproductible: /


@ tws061105, vérifiez les modifications pour voir si cela résout votre problème. Vous ne devriez pas avoir besoin de faire de mappage entre Date et integer , si la classe de colonne access_date est un factor , ou vous le convertissez en un comme décrit ci-dessus, qui mappera les dates pour vous



1
votes

Solution intelligente de @desc. Si votre date est formatée en tant que date et que vous souhaitez qu'elle soit numérique, le script ci-dessous fonctionne. Cela utilise le data.example de desc (merci), mais le format de la date est j / m / a, c'est pourquoi format dans as.Date est " % d /% m /% Y ".

> data.example = structure(list(pt_id = c(1234L, 1234L, 1234L, 1234L, 4567L, 4567L, 
+                                         4567L, 4567L, 8900L, 8900L, 8900L, 8900L), assess_date = structure(c(1L, 
+                                                                                                              2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("1/1/2019", 
+                                                                                                                                                                      "1/2/2019", "1/3/2019", "1/4/2019"), class = "factor"), assess_id = c(64L, 
+                                                                                                                                                                                                                                            64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L, 64L)), class = "data.frame", row.names = c(NA, 
+                                                                                                                                                                                                                                                                                                                                         -12L))
> 
> data.example$assess_date <- as.Date(data.example$assess_date, format = "%d/%m/%Y")
> data.example$assess_num <- as.numeric(format(data.example$assess_date, "%m"))
> data.example
   pt_id assess_date assess_id assess_num
1   1234  2019-01-01        64          1
2   1234  2019-02-01        64          2
3   1234  2019-03-01        64          3
4   1234  2019-04-01        64          4
5   4567  2019-01-01        64          1
6   4567  2019-02-01        64          2
7   4567  2019-03-01        64          3
8   4567  2019-04-01        64          4
9   8900  2019-01-01        64          1
10  8900  2019-02-01        64          2
11  8900  2019-03-01        64          3
12  8900  2019-04-01        64          4


2 commentaires

Merci @Andrew! Cela semble dépendre des évaluations effectuées au cours des différents mois, ce qui n'est pas toujours le cas pour moi (mais je reconnais que cela correspond à l'exemple que j'ai fourni). Merci de votre contribution, et merci pour la critique concernant la publication d'exemples reproductibles


Bien sûr, et je suis heureux que vous ayez trouvé une solution qui fonctionne pour vos données! De plus, il est habituel de cocher la case à côté de la réponse qui résout votre problème si votre problème est résolu (c'est-à-dire pour accepter la réponse de desc). Merci pour le suivi aussi!



0
votes

Merci beaucoup pour les suggestions. Malheureusement, je n'ai pas réussi à faire fonctionner l'une des solutions suggérées, mais j'ai trouvé exactement ce dont j'avais besoin dans la fonction getanID du package splitstackshape, selon le code suivant:

getanID (data, "pt_id") - a fonctionné comme un charme!


0 commentaires