J'ai la trame de données suivante df avec des données longitudinales au format long (voir ci-dessous). Je voudrais créer une nouvelle variable appelée new.var basée sur certaines conditions. Cette nouvelle variable doit être 1, si la première valeur de postLin pour une personne est> 0 mais <= 1 ou si la valeur de postLin == 0 et la valeur de preLin == 0. < strong> Il ne peut y en avoir qu'un seul 1 sur new.var par personne (ID).

df <- read.table(text=
"ID       preLin   postLin      
800057    -8.55    0               
800057    -6.34    0           
800057    -5.34    0           
800057    -4.34    0         
800057        0    0.33   
800119    -0.88    0  
800119        0    0           
800119        0    1       
834011     -4.1    0 
834011     -3.1    0   
834341        0    1.34 
834341        0    2.34   
834341        0    3.34   
834341        0    5.34    
834341        0    6.66  
800125        0    0
800125        0    2.14
897177    -0.33    0 
897177        0    0.67 
897177        0    1.67", header=TRUE)

Tout d'abord, j'ai essayé ce code:

df$new.var1 <- ifelse(df$preLin == 0 & (df$postLin >= 0 & df$postLin <= 1), 1, 0)

Cependant, pour l'ID 800119, il y aura alors deux 1.

Mon résultat attendu ressemblerait à ceci:

df_new <- read.table(text=
"ID       preLin   postLin    new.var  
800057    -8.55    0          0         
800057    -6.34    0          0  
800057    -5.34    0          0
800057    -4.34    0          0     
800057        0    0.33       1 
800119    -0.88    0          0 
800119        0    0          1  
800119        0    1          0
834011     -4.1    0          0 
834011     -3.1    0          0 
834341        0    1.34       0
834341        0    2.34       0
834341        0    3.34       0  
834341        0    5.34       0    
834341        0    6.66       0
800125        0    0          1
800125        0    2.14       0
897177    -0.33    0          0
897177        0    0.67       1
897177        0    1.67       0", header=TRUE) 

Quelqu'un connaît-il une solution à mon problème? Merci d'avance!

0
Mary B. 1 juil. 2020 à 18:07

2 réponses

Meilleure réponse

Le résultat attendu provient de la déclaration de la condition dans ifelse comme suit:

df$new.var1 <- ifelse((df$postLin > 0 & df$postLin < 1) | (df$preLin == 0 & df$postLin ==0), 1, 0)

value = 1 si df $ postLin obtient des valeurs comprises entre 0 et 1 (mais pas entre 0 et 1) ou si les deux df $ preLin et df $ postLin valent 0. Sinon valeur = 0

Résultat:

       ID preLin postLin new.var1
1  800057  -8.55    0.00        0
2  800057  -6.34    0.00        0
3  800057  -5.34    0.00        0
4  800057  -4.34    0.00        0
5  800057   0.00    0.33        1
6  800119  -0.88    0.00        0
7  800119   0.00    0.00        1
8  800119   0.00    1.00        0
9  834011  -4.10    0.00        0
10 834011  -3.10    0.00        0
11 834341   0.00    1.34        0
12 834341   0.00    2.34        0
13 834341   0.00    3.34        0
14 834341   0.00    5.34        0
15 834341   0.00    6.66        0
16 800125   0.00    0.00        1
17 800125   0.00    2.14        0
18 897177  -0.33    0.00        0
19 897177   0.00    0.67        1
20 897177   0.00    1.67        0

Remarque : conserver la condition <= 1 en entraînera une supplémentaire dans le troisième 800119, comme @ shirewoman2 l'a dit dans son commentaire

0
davidnortes 1 juil. 2020 à 15:36

Voici une approche qui utilise tidyverse. Il regroupe vos identifiants s and uses the filter you want. A little helper columns is build which finds the first occurence in postLin, it is removed later. mutate with ifelse applies your rules. Then the result is joined with the original DF and NA s sont transformés en zéros.

library(tidyverse)


df %>%
  group_by(ID) %>%
  dplyr::filter(postLin > 0 | (postLin == 0 & preLin == 0)) %>%
  dplyr::mutate(
    first = dplyr::first(postLin)
  ) %>%
  mutate(new.var = ifelse((postLin == first & postLin < 1), 1, 0)) %>%
  select(-c(first)) %>%
  right_join(df, by = c("ID", "preLin", "postLin")) %>%
  mutate(new.var = ifelse(is.na(new.var), 0, new.var)) %>%
  arrange(ID, preLin, postLin)
#> # A tibble: 20 x 4
#> # Groups:   ID [6]
#>        ID preLin postLin new.var
#>     <int>  <dbl>   <dbl>   <dbl>
#>  1 800057  -8.55    0          0
#>  2 800057  -6.34    0          0
#>  3 800057  -5.34    0          0
#>  4 800057  -4.34    0          0
#>  5 800057   0       0.33       1
#>  6 800119  -0.88    0          0
#>  7 800119   0       0          1
#>  8 800119   0       1          0
#>  9 800125   0       0          1
#> 10 800125   0       2.14       0
#> 11 834011  -4.1     0          0
#> 12 834011  -3.1     0          0
#> 13 834341   0       1.34       0
#> 14 834341   0       2.34       0
#> 15 834341   0       3.34       0
#> 16 834341   0       5.34       0
#> 17 834341   0       6.66       0
#> 18 897177  -0.33    0          0
#> 19 897177   0       0.67       1
#> 20 897177   0       1.67       0
0
MarBlo 1 juil. 2020 à 17:08