使用purrr根据现有变量的值创建几个新变量

时间:2018-12-30 17:03:25

标签: r iteration purrr

编辑:添加了示例df

我有一个3项清单(选项a,b,c),参与者可以在其中选择尽可能多的答复。在我的数据中,这些响应存储在三个二进制响应选项中(q4 ___ a,q4 ___ b,q4 ___ c)。我在四个不同的时间点(1、2、3、4)具有相同的数据,因此我的变量编码如下:

q4_1___a
q4_1___b
q4_1___c
q4_2___a
q4_2___b

等,其中q4是词干,整数是收集数据的时间,字母是响应选项。这是一个示例数据框:

df <- data.frame(
 q4_1___a = rbinom(10, 1, .5),
 q4_1___b = rbinom(10, 1, .5),
 q4_1___c = rbinom(10, 1, .5),
 q4_2___a = rbinom(10, 1, .5),
 q4_2___b = rbinom(10, 1, .5),
 q4_2___c = rbinom(10, 1, .5),
 q4_3___a = rbinom(10, 1, .5),
 q4_3___b = rbinom(10, 1, .5),
 q4_3___c = rbinom(10, 1, .5),
 q4_4___a = rbinom(10, 1, .5),
 q4_4___b = rbinom(10, 1, .5),
 q4_4___c = rbinom(10, 1, .5)
)

我需要创建“组”变量,该变量在每个时间点组合三个不同的二进制响应变量的结果。我可以使用以下代码在时间点1做到这一点:

df%>%
 mutate(q4_1_group = case_when(
  q4_1___a == 1 & q4_1___b == 0 & q4_1___c == 0 ~ "a",
  q4_1___a == 0 & q4_1___b == 1 & q4_1___c == 0 ~ "b",
  q4_1___a == 0 & q4_1___b == 0 & q4_1___c == 1 ~ "c",
  q4_1___a == 1 & q4_1___b == 1 & q4_1___c == 0 ~ "ab",
  q4_1___a == 1 & q4_1___b == 0 & q4_1___c == 1 ~ "ac",
  q4_1___a == 0 & q4_1___b == 1 & q4_1___c == 1 ~ "bc",
  q4_1___a == 1 & q4_1___b == 1 & q4_1___c == 1 ~ "abc"
 ))

我很难弄清楚从这儿到哪里去遍历所有四个时间点。本质上,我需要将所有变量名称中的1更改为2、3和4,以便:

df%>%
 mutate(q4_[i]_group = case_when(
  q4_[i]___a == 1 & q4_[i]___b == 0 & q4_[i]___c == 0 ~ "a",
  q4_[i]___a == 0 & q4_[i]___b == 1 & q4_[i]___c == 0 ~ "b",
  q4_[i]___a == 0 & q4_[i]___b == 0 & q4_[i]___c == 1 ~ "c",
  q4_[i]___a == 1 & q4_[i]___b == 1 & q4_[i]___c == 0 ~ "ab",
  q4_[i]___a == 1 & q4_[i]___b == 0 & q4_[i]___c == 1 ~ "ac",
  q4_[i]___a == 0 & q4_[i]___b == 1 & q4_[i]___c == 1 ~ "bc",
  q4_[i]___a == 1 & q4_[i]___b == 1 & q4_[i]___c == 1 ~ "abc"
 ))

其中[i]对应于c(1:4)之类的东西。我觉得肯定有一种使用purrr来做到这一点的简单方法,但是我正在努力弄清楚。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

我们可以创建一个关键值数据集,然后进行联接

library(tidyverse)
keydat <- data.frame(a = c(1, 0, 0, 1, 1, 0, 1),
                     b = c(0, 1, 0, 1, 0, 1, 1), 
                     c = c(0, 0, 1, 0, 1, 1, 1),
                     group = c("a", "b", "c", "ab", "ac", "bc", "abc"), 
            stringsAsFactors = FALSE)
nm1 <- unique(sub("__.*", "", names(df)))
split.default(df, as.numeric(gsub("^q\\d+_|__.*$", "", names(df)))) %>%
     map(~ .x %>%
              left_join(keydat, by = setNames(letters[1:3], names(.x)))) %>%
     bind_cols %>%
     rename_at(vars(matches('group')), ~paste0(nm1, '_group'))