如何遍历各列,检查某列中是否存在特定值,对新列进行突变,如果存在则输入1,否则输入0?

Joh*_*ton 6 r dataframe dplyr data-cleaning

我正在做一个研究项目,并且输入的表格中的一种还不太适合分析,因此我试图对其进行重组。当前,每一行都是考生,每一列都是他们错误回答的问题,以升序输入。因此,对于第一行,条目可以分别读取第一,第二和第三列的“ Q1”,“ Q3”,“ Q9”等。总共有25个问题。

我的目标是重组数据,以便每个问题都有一列。如果考生正确回答了该问题,则相应列的条目为1,否则为0。

有一种蛮力的方法似乎起作用。可以分别更改每列并检查每列中的每个值。但是,这里有25个问题,所有这些键入似乎效率都很低,所以我怀疑必须有更好的方法。

暴力代码如下所示:

df %>%
  mutate(Q3 == ifelse(col1 == "Q3" | col2 == "Q3" | col3 == "Q3", 0, 1))
Run Code Online (Sandbox Code Playgroud)

在这里,col1,col2,col3都是可能包含Q3的所有列,这可能是测试者出错的问题。如果其中有一个,我们输入0。否则,我们输入1。

有25个问题,代码变得太长。

编辑:数据框的示例如下所示。

sample <- "ID   Col1  Col2  Col3  Col4
1          100   Q1     
2          101   Q3    Q4
3          102   Q2    Q3    Q4   
4          103   
5          104   Q4
6          105   Q1    Q2    Q3    Q4 "
Run Code Online (Sandbox Code Playgroud)

所需的输出如下:

sample <- "ID    Q1    Q2    Q3    Q4
1          100   0     1     1     1
2          101   1     1     0     0
3          102   1     0     0     0   
4          103   1     1     1     1
5          104   1     1     1     0 
6          105   0     0     0     0 "
Run Code Online (Sandbox Code Playgroud)

G. *_*eck 2

1)假设DF如最终使用的注释中所示可重复地sapply创建指标矩阵,然后cbind将其添加到ID列中。最后让名字好听一些。没有使用任何包。

ques <- function(i) paste0("Q", 1:25) %in% unlist(DF[i, -1])
DFout <- cbind(DF[1], +t(sapply(1:nrow(DF), ques)))
names(DFout)[-1] <- paste0("Q", names(DFout[-1]))
Run Code Online (Sandbox Code Playgroud)

前 5 列是:

> DFout[1:5]

   ID Q1 Q2 Q3 Q4
1 100  1  0  0  0
2 101  0  0  1  1
3 102  0  1  1  1
4 103  0  0  0  0
5 104  0  0  0  1
6 105  1  1  1  1
Run Code Online (Sandbox Code Playgroud)

2)另一种可能性是将输入转换为长格式,然后用于xtabs从中创建表。

library(dplyr)
library(tidyr)

tab <- DF %>% 
  gather(key, Question, -ID) %>%
  filter(nzchar(Question)) %>%
  mutate(Question = factor(Question, paste0("Q", 1:25))) %>%
  xtabs(~ ID + Question, .)
Run Code Online (Sandbox Code Playgroud)

给这张表。我们显示前 5 列:

> tab[, 1:5]

     Question
ID    Q1 Q2 Q3 Q4
  100  1  0  0  0
  101  0  0  1  1
  102  0  1  1  1
  104  0  0  0  1
  105  1  1  1  1
Run Code Online (Sandbox Code Playgroud)

如果结果是数据框很重要,则添加:

library(tibble)

tab %>% 
  as.data.frame.matrix %>% 
  rownames_to_column(var = "ID")    
Run Code Online (Sandbox Code Playgroud)

笔记

sample <- "rows ID   Col1  Col2  Col3  Col4
1          100   Q1     
2          101   Q3    Q4
3          102   Q2    Q3    Q4   
4          103   
5          104   Q4
6          105   Q1    Q2    Q3    Q4"
DF <- read.table(text = sample, header = TRUE, fill = TRUE, as.is = TRUE,
  strip.white = TRUE)[-1]
Run Code Online (Sandbox Code Playgroud)