dplyr为两个因子变量生成全套虚拟交互作用项

时间:2019-01-11 01:04:39

标签: r dplyr tidyr forcats

比方说,我有两个因子变量,在我的情况下,一个变量具有很多因子(multi.factor),而另一个变量只有两个因子(two.factor),它本身就是一个虚拟变量。 / p>

df <- data.frame(two.factor = rep(c(0,1), 4)) %>%
  mutate(multi.factor = ceiling(row_number()/2))

df

#>   two.factor multi.factor
#> 1          0            1
#> 2          1            1
#> 3          0            2
#> 4          1            2
#> 5          0            3
#> 6          1            3
#> 7          0            4
#> 8          1            4

如何使用dplyr或其他tidyverse方法为这两个变量创建一组虚拟交互作用项?换句话说,我需要4 * 1 = 4个新的虚拟变量,如果two.factor为1且multi.factor是在交互项中命名的因子,则为1,否则为0。是:

df %<>%
  mutate(interact.1 = case_when(multi.factor == 1 & two.factor == 1 ~ 1, TRUE ~ 0)) %>%
  mutate(interact.2 = case_when(multi.factor == 2 & two.factor == 1 ~ 1, TRUE ~ 0)) %>%
  mutate(interact.3 = case_when(multi.factor == 3 & two.factor == 1 ~ 1, TRUE ~ 0)) %>%
  mutate(interact.4 = case_when(multi.factor == 4 & two.factor == 1 ~ 1, TRUE ~ 0))

df
#>   two.factor multi.factor interact.1 interact.2 interact.3 interact.4
#> 1          0            1          0          0          0          0
#> 2          1            1          1          0          0          0
#> 3          0            2          0          0          0          0
#> 4          1            2          0          1          0          0
#> 5          0            3          0          0          0          0
#> 6          1            3          0          0          1          0
#> 7          0            4          0          0          0          0
#> 8          1            4          0          0          0          1

(我还没有使multi.factortwo.factor成为实际因素,而我只是使用整数来表示使复制保持简单的因素水平。在我的实际数据中,{{1} }是字符串。我怀疑multi.factor解决方案将不在乎。)

1 个答案:

答案 0 :(得分:0)

假设multi.factor是一个因素,则可以使用map为每个级别创建一个新列:

library(tidyverse)

df <- data.frame(two.factor = rep(c(0,1), 4)) %>%
  mutate(multi.factor = as.factor(ceiling(row_number()/2)))

df %>% 
  bind_cols(
    map( levels(df$multi.factor),
         function(x)
           df %>% transmute(!!paste0("interact.",x) := (multi.factor == x) * two.factor)
    )
  )