通过观察前后改变虚拟变量

Mutate dummy variable with observation before and after

我有一个 title-day 面板数据集 (df1)。对于每个标题和给定的日期,卷(卷)都被编码。有一个变量,您可以将其视为处理 (v1)。在这个数据集中总是有一种治疗,但治疗开始的日期因标题而异。当治疗开始时,它会一直持续到疗程结束。

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)

我尝试改变一个虚拟变量,该变量指示标题在处理到位之前和之后是否有任何音量(非零)。其中 1 在标题在治疗开始之前和之后获得音量的情况下编码。当标题在治疗开始前没有音量或在治疗开始后没有音量时编码为 0。数据框应如下所示:

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)

希望大家能帮帮我。

这是一个使用 dplyr 的方法:

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 

在您想要的输出中将 Dummy 编码为 0/1:

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

您可以使用 ave 并在所有处理的 volumes 为零时使用 if/else 进行案例处理。

output <- transform(df1, 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
}))
#    title day volume v1 new_v
# 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

或者如果您需要 dplyr

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
}))

对于每个title,我们可以检查在治疗前(v1 == 0)和治疗后(v1 == 1)是否有any volume > 0

这可以使用 dplyr 来完成:

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

data.table 中的相同逻辑:

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