r - 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 个调查问题,我想尽可能地自动化这个过程。值得注意的事情要记住:
- 并非所有调查问题都有相同数量的选项(即问题 2 有 2 个选项,因此有 2 列,而问题 10 有 8 个选项和 8 列)
- 一些值是字符串,而不是 1 或 NA
总是乐于学习,
最好的,
玛丽亚
解决方案
这是一种从宽到长的转换,我们可以使用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
语句中。
推荐阅读
- oracle - 以路径作为查询列值的 Oracle JSON_QUERY
- javascript - 如何生成随机数,然后排除数字数组
- asp.net-web-api - 从 .NET Framework 4.6 的 azure-service-fabric 服务调用 OWIN 启动调用以使用 Okta
- c++ - 如何在我的主目录中包含整个文件夹?
- python - 如何将此 curl 命令转换为 python?
- java - CodecNotFoundException:未找到请求操作的编解码器:[地图
<-> java.util.Map] - python - 使用 Python 创建 JSON 对象
- typescript - NestJS 使用来自 ConfigService 的配置注入 Dropox 实例
- python - 如何根据矩阵的构造跟踪矩阵的特征值和特征向量
- python - 缝合用户 ID 以进行点击跟踪