简体   繁体   English

在 R 中嵌套 ifelse 以跨多个列进行变异

[英]Nesting ifelse in R to mutate across multiple columns

I am wrangling data in R from an experiment with, for simplicity, 2 questions and 3 conditions.为了简单起见,我在 R 中对数据进行了争论,其中包含 2 个问题和 3 个条件。 Each participant is assigned to 1 of the 3 conditions, every participant answers both questions.每个参与者被分配到 3 个条件中的一个,每个参与者都回答两个问题。

The data is currently organized so that each column contains the answers for one question within one condition:当前对数据进行了组织,以便每一列包含一个条件下一个问题的答案:

Respondent.ID <- c("ID1", "ID2", "ID3", "ID4", "ID5", "ID6", "ID7", "ID8", "ID9")
Q1.CondA <- c("Correct", "Incorrect", "I don't know", "", "", "", "", "", "")
Q1.CondB <- c("", "", "", "Incorrect", "Correct", "I don't know", "", "", "")
Q1.CondC <- c("", "", "", "", "", "", "I don't know", "Correct", "Incorrect")
Q2.CondA <- c("Incorrect", "Correct", "I don't know", "", "", "", "", "", "")
Q2.CondB <- c("", "", "", "I don't know", "Correct", "Incorrect", "", "", "")
Q2.CondC <- c("", "", "", "", "", "", "Correct", "Incorrect", "I don't know")

current<- data.frame(Respondent.ID, Q1.CondA, Q1.CondB, Q1.CondC, Q2.CondA, Q2.CondB, Q2.CondC)

I want to reorganize the data so that one column shows the assigned condition, one column show the answers for question 1 for all conditions, and 1 column shows the answers for question 2 for all conditions:我想重新组织数据,以便一列显示分配的条件,一列显示所有条件的问题 1 的答案,以及 1 列显示所有条件的问题 2 的答案:

Respondent.ID <- c("ID1", "ID2", "ID3", "ID4", "ID5", "ID6", "ID7", "ID8", "ID9")
Condition <- c("A", "A", "A", "B", "B", "B", "C", "C", "C")
Q1 <- c("Correct", "Incorrect", "I don't know", "Incorrect", "Correct", "I don't know", "I don't know", 
"Correct", "Incorrect")
Q2 <- c("Incorrect", "Correct", "I don't know", "I don't know", "Correct", "Incorrect", "Correct", "Incorrect", "I don't know")
desired<- data.frame(Respondent.ID, Condition, Q1, Q2)

I can do this in Excel by nesting If-statements (IF cell non-blank, THEN duplicate cell, ELSE IF next cell non-blank, THEN duplicate next cell, ELSE IF...).我可以在 Excel 中通过嵌套 If 语句(如果单元格非空白,然后复制单元格,ELSE IF 下一个单元格非空白,然后复制下一个单元格,ELSE IF...)来执行此操作。 But I would rather do everything in R if possible.但如果可能的话,我宁愿在 R 中做所有事情。

The drag to copy function in Excel means that I can enter this cell-level nested If-statement once, and then it is automatically changed for the other cells.在 Excel 中拖动复制 function 意味着我可以输入这个单元格级别的嵌套 If 语句一次,然后它会自动更改为其他单元格。 My actual dataset has 40 questions, 8 conditions, and 800 participants, so doing this manually isn't an option.我的实际数据集有 40 个问题、8 个条件和 800 名参与者,因此无法手动执行此操作。

In R, I have tried combining mutate() with nested ifelse() statements:在 R 中,我尝试将 mutate() 与嵌套的 ifelse() 语句结合起来:

dplyr::mutate(current, Condition = ifelse(current$Q1.CondA != ' ', 'A', 
       ifelse(current$Q1.CondB !=' ', 'B',
              ifelse(current$Q1.CondC !=' ', 'C', ' '))))

But it's just looking up the first element in the column, finding a nonblank, and then returning a new 'Condition' column that is filled with 'A'.但它只是查找列中的第一个元素,找到一个非空白,然后返回一个新的填充有“A”的“条件”列。

Is there a way get this to work in R to get from my current data frame to my desired data frame?有没有办法让它在 R 中工作以从我当前的数据帧到我想要的数据帧?

Another approach is to first pivot the table using tidyr , so all columns except the ID are gathered into one column.另一种方法是首先 pivot 使用tidyr表,因此除 ID 之外的所有列都聚集到一个列中。

library(tidyr)
current %>% 
  tidyr::pivot_longer(cols = -Respondent.ID)

The resulting name column can then be separated into 2 columns, using ".Cond"然后可以使用".Cond"将生成的name列分为 2 列

current %>% 
  tidyr::pivot_longer(cols = -Respondent.ID) %>% 
  tidyr::separate(name, c("question_id", "condition"), sep = ".Cond")

Removing empty strings and pivoting wider will produce desired output移除空弦并旋转更宽将产生所需的 output

current %>% 
  tidyr::pivot_longer(cols = -Respondent.ID) %>% 
  tidyr::separate(name, c("question_id", "condition"), sep = ".Cond") %>% 
  dplyr::filter(value != "") %>% 
  tidyr::pivot_wider(names_from = question_id)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM