1
votes

Variable fictive de mutation avec observation avant et après

J'ai un ensemble de données de panneau jour-titre (df1). Pour chaque titre et jour donné, le volume (volume) est codé. Il existe une variable que vous pourriez considérer comme un traitement (v1). Dans cet ensemble de données, il y a toujours un traitement, mais le jour du début du traitement diffère selon le titre. Lorsque le traitement commence, il reste jusqu'à la fin de la période.

title <- rep(c("x", "y", "z"), each = 5)
day <- rep(c(0,1,2,3,4), times = 3)
volume <- c(0,0,1,1,2,3,0,0,0,0,3,3,4,2,1)
v1 <- c(0,0,1,1,1,0,1,1,1,1,0,0,0,1,1)
new_v <- c(0,0,0,0,0,0,0,0,0,0,1,1,1,1,1)
output <- data.frame(title,day,volume,v1,new_v)

J'essaie de muter une variable factice qui indique si le titre a obtenu un volume (non nul) avant ET après la mise en place du traitement. Où 1 est codé dans les situations où le titre a obtenu du volume avant et après le début du traitement. 0 est codé lorsque le titre n'a pas de volume avant ou pas de volume après le début du traitement. Le dataframe devrait ressembler à ceci:

title <- rep(c("x", "y", "z"), each = 5)
day <- rep(c(0,1,2,3,4), times = 3)
volume <- c(0,0,1,1,2,3,0,0,0,0,3,3,4,2,1)
v1 <- c(0,0,1,1,1,0,1,1,1,1,0,0,0,1,1)
df1 <- data.frame(title,day,volume,v1)

J'espère que vous pourrez m'aider ici.


2 commentaires

Si j'ai bien compris la question, c'est parce que le volume sur tous les jours de traitement est de 0 pour y


Exactement Dominik. C'est 0 car il devrait y avoir du volume avant et après le traitement. Y n'a que du volume avant le traitement mais pas après.


3 Réponses :


0
votes

Voici une approche utilisant dplyr:

df1 %>% 
  group_by(title, v1) %>% 
  mutate(summe = sum(volume)) %>% 
  group_by(title) %>% 
  mutate(dummy_volume = as.integer(all(summe > 0))) %>% 
  select(-summe)

# A tibble: 15 x 5
# Groups:   title [3]
   title   day volume    v1 dummy_volume
   <fct> <dbl>  <dbl> <dbl>        <int>
 1 x         0      0     0            0
 2 x         1      0     0            0
 3 x         2      1     1            0
 4 x         3      1     1            0
 5 x         4      2     1            0
 6 y         0      3     0            0
 7 y         1      0     1            0
 8 y         2      0     1            0
 9 y         3      0     1            0
10 y         4      0     1            0
11 z         0      3     0            1
12 z         1      3     0            1
13 z         2      4     0            1
14 z         3      2     1            1
15 z         4      1     1            1

Avec le Dummy codé comme 0/1 comme dans votre sortie souhaitée:

library(dplyr)

df1 %>% 
  group_by(title, v1) %>% 
  mutate(summe = sum(volume)) %>% 
  group_by(title) %>% 
  mutate(dummy_volume = all(summe > 0)) %>% 
  select(-summe)

# A tibble: 15 x 5
# Groups:   title [3]
   title   day volume    v1 dummy_volume
   <fct> <dbl>  <dbl> <dbl> <lgl>       
 1 x         0      0     0 FALSE       
 2 x         1      0     0 FALSE       
 3 x         2      1     1 FALSE       
 4 x         3      1     1 FALSE       
 5 x         4      2     1 FALSE       
 6 y         0      3     0 FALSE       
 7 y         1      0     1 FALSE       
 8 y         2      0     1 FALSE       
 9 y         3      0     1 FALSE       
10 y         4      0     1 FALSE       
11 z         0      3     0 TRUE        
12 z         1      3     0 TRUE        
13 z         2      4     0 TRUE        
14 z         3      2     1 TRUE        
15 z         4      1     1 TRUE 

p >


1 commentaires

Je choisis cette réponse pour sa simplicité.



0
votes

Vous pouvez utiliser ave et effectuer un traitement de cas en utilisant if / else lorsque tous les volumes traités sont à zéro.

library(dplyr)
output <- df1 %>% 
  mutate(new_v=ave(volume, title, FUN=function(x) {
  rr <- sum(x[v1 %in% 0], na.rm=T) > 0
  if (sum(x[v1 %in% 1], na.rm=T) == 0) 0
  else rr
}))


0 commentaires

0
votes

Pour chaque titre nous pouvons vérifier s'il y a un volume> 0 avant le traitement ( v1 == 0 code >) et après traitement ( v1 == 1 ).

Cela peut être fait en utilisant dplyr :

library(data.table)
setDT(df1)[, new_v := +(any(volume[v1 == 1] > 0) && 
                        any(volume[v1 == 0] > 0)), title]

Ou la même logique dans data.table : p>

library(dplyr)
df1 %>%
  group_by(title) %>%
  mutate(new_v = +(any(volume[v1 == 1] > 0) && any(volume[v1 == 0] > 0)))

#  title   day volume    v1 new_v
#   <chr> <dbl>  <dbl> <dbl> <int>
# 1 x         0      0     0     0
# 2 x         1      0     0     0
# 3 x         2      1     1     0
# 4 x         3      1     1     0
# 5 x         4      2     1     0
# 6 y         0      3     0     0
# 7 y         1      0     1     0
# 8 y         2      0     1     0
# 9 y         3      0     1     0
#10 y         4      0     1     0
#11 z         0      3     0     1
#12 z         1      3     0     1
#13 z         2      4     0     1
#14 z         3      2     1     1
#15 z         4      1     1     1


0 commentaires