首页 > 解决方案 > R 中的整理:如何根据向量将我的二进制列折叠成字符?

问题描述

我正在整理 R 中的数据,并希望使用迭代向量项的函数将多列变为 1。我想知道您是否可以帮助我:

我的数据基于一项包含 32 个问题的调查。每个问题都有多个答案。每个答案都是一列,有选项 1 和 NA。

对于一个问题,数据集的一部分可以复制如下:

XV2_1 <- c(1,NA,NA,NA)
XV2_2 <- c(NA,1,NA,NA)
XV2_3 <- c(NA,NA,NA,1)
XV2_4 <- c(NA,NA,1,NA)
id <- c(12,13,14,15)

dat <- data.frame(id,XV2_1, XV2_2, XV2_3,XV2_4)

> dat
  id XV2_1 XV2_2 XV2_3 XV2_4
1 12     1    NA    NA    NA
2 13    NA     1    NA    NA
3 14    NA    NA    NA     1
4 15    NA    NA     1    NA

这是我想要的数据(

question_2_answers <- c("Yellow","Blue","Green","Orange") #this is a vector based on the answers of the questionnaire

collapsed <- c("Yellow","Blue","Orange","Green")

collapsed_dataframe <- data.frame(id,collapsed)
>collapsed_dataframe
  id   X2
1 12   Yellow
2 13   Blue
3 14   Green
4 15   Orange

到目前为止,我尝试了一系列与 mutate 结合的“ifelse”:

library(tidyverse)
question_2_answers <- c("Yellow","Blue","Green","Orange") #this is a vector based on the answers of the questionnaire

dat %>%
  mutate(
    Colour = tidy_Q2(question_2_answers,XV2_1,XV2_2,XV2_3,XV2_4)
  )

tidy_Q2 <- function(a,b,c,d,e) {
  ifelse(b == 1, a[1],ifelse(
    c==1,a[2],ifelse(
      d==1,a[3],a[4])))
}

但是,我的输出不如预期:

  id XV2_1 XV2_2 XV2_3 XV2_4 Colour
1 12     1    NA    NA    NA Yellow
2 13    NA     1    NA    NA   <NA>
3 14    NA    NA    NA     1   <NA>
4 15    NA    NA     1    NA   <NA>

我希望它如下所示:

  id XV2_1 XV2_2 XV2_3 XV2_4 Colour
1 12     1    NA    NA    NA Yellow
2 13    NA     1    NA    NA   Blue
3 14    NA    NA    NA     1   Green
4 15    NA    NA     1    NA   Orange

有谁知道消除错误的方法?我想问的另一个问题是,我的代码是否可以更高效?在此之后我有 32 个调查问题,我想尽可能地自动化这个过程。值得注意的事情要记住:

总是乐于学习,

最好的,

玛丽亚

标签: rdplyrtidyr

解决方案


这是一种从宽到长的转换,我们可以使用tidyr::gather

首先,我们将颜色设置为相应行的列名:

# Replace column names (except for the `id` column) with color values
colnames(dat)[-1] <- c("Yellow","Blue","Orange","Green")

dat
  id Yellow Blue Orange Green
1 12      1   NA     NA    NA
2 13     NA    1     NA    NA
3 14     NA   NA     NA     1
4 15     NA   NA      1    NA

然后,我们收集非 id 列并删除 NA 值:

library(tidyverse)
dat %>%
    gather(X2, val, -id) %>%   # Gather color cols from wide to long format
    filter(!is.na(val)) %>%    # Drop rows with NA values
    select(-val)               # Remove the unnecessary `val` column

  id     X2
1 12 Yellow
2 13   Blue
3 15 Orange
4 14  Green

这将适用于任意数量的列(您只需要指定您不想收集的所有列并保留具有非NA值的行。如果您希望其他条件排除一行(例如,如果0'unknown'应该算作非答案,或仅'correct'算作答案),那么您应该将这些条件添加到filter语句中。


推荐阅读