将列名称整理成变量

Bri*_*ats 1 r dplyr tidyr purrr

我从调查中得到了一个非常混乱的数据集,其中每个复选框都是一个指示变量.因此,不要将性别(或种族)作为带有M/F作为条目的变量,而是有一个gender_m和一个带有指标的gender_f列.

简化示例:

df <- tribble(
  ~id, ~gender_m, ~gender_f,
  #--|----------|---------
  1L , 0        , 1,
  2L , 1        , 0,
  3L , 0        , 0,
  4L , 1        , 1
  )
Run Code Online (Sandbox Code Playgroud)

我想要的输出是:

  result <- tribble(
    ~id, ~gender,
    #--|----------
  1L , 'f',
  2L , 'm',
  3L , 'Missing',
  4L , 'More than 1 selected'
)
Run Code Online (Sandbox Code Playgroud)

对于像性别这样的东西,只有2列,它很容易硬编码,但我试图使它尽可能通用,因为像种族(或你使用的编程语言)这样的东西有多种可能性.

我有近千列但不到20个实际变量.所有列都是表格<variable_name>_<potential_value>.

我确定我错过了一些整洁的功能,但我的googlefu今天似乎很弱.

Mar*_*ius 5

许多tidy函数在列中比行更好,所以如果转换为long,这会变得更容易:

df_long = df %>%
    gather(Item, Response, starts_with("gender"))

cleaned = df_long %>%
    mutate(Item = str_match(Item, "(.*)_(.*)")[, 3]) %>%
    group_by(id) %>%
    summarize(RespCleaned = case_when(
        sum(Response) == 0 ~ "Missing",
        sum(Response) == 1 ~ Item[Response == 1][1],
        sum(Response) > 1 ~ "More than 1 selected"
    ))

df = df %>% left_join(cleaned, by = "id")
Run Code Online (Sandbox Code Playgroud)

如果您有大量具有这些0/1指标的项目用于回复,则使用响应总和应该推广到具有2个以上选项的项目.您只需要替换starts_with("gender")另一个选择器而不是选择相关列.