【问题标题】:mutate_ column using a calculated column name in dplyrmutate_ column 使用 dplyr 中计算的列名
【发布时间】:2016-10-31 06:18:16
【问题描述】:

我有以下data.frame

qs <- structure(list(Question = c("This is a question", "This is a question"), 
Correct_Answer = c("D", "B"), 
Answer.A = c("This is an answer", "This is an answer"), 
Answer.B = c("This is an answer", "This is an answer"), 
Answer.C = c("This is an answer", "This is an answer"), 
Answer.D = c("This is an answer", "This is an answer"), 
Explanation = c("Just because!", "Just because!"), 
Response_A = c("", ""), 
Response_B = c("", ""), 
Response_C = c("", ""), 
Response_D = c("", "")), 
.Names = c("Question", "Correct_Answer", "Answer.A", "Answer.B",
           "Answer.C", "Answer.D", "Explanation", "Response_A", 
           "Response_B", "Response_C", "Response_D"), 
row.names = 1:2, class = "data.frame")

我想为每个问题设置Response_X 值以匹配Explanation。例如在第一行,Correct_Answer 是 D,所以 Response_D 应该等于解释,其他 Responses_ 应该保持空白。

我尝试了以下方法:

library(dplyr)

qs %>% rowwise() %>% mutate_(.dots=setNames(paste(Explanation), 
                          paste0("Response_",Correct_Answer)))

它给出:

Error in paste0("Response_", Correct_Answer) : 
  object 'Correct_Answer' not found

我觉得我应该在这里使用 apply,但不确定如何。

【问题讨论】:

  • 我认为观察到的和实际的答案应该是数据集的观察(行),而变量的问题,即列应该被称为Q1Q2Q3,等等Explanation 将保持一个变量并为每个答案重复。
  • 目前每一行都是一个单独的问题。以及仅附于该问题的所有答案。它说 Response_ 是计算机将对任何提交的答案给出的响应。我希望在对正确答案的回应中做出解释。这更有意义吗?
  • 好的。我认为您不需要更多大部分为空的列。如果可能,请尝试使用“整洁”的数据方法。请参阅下面的答案。
  • 问题是我上面使用的格式是将数据导入另一个程序所需的格式。即使我有一个更精细的数据模型,我仍然需要将它转换为空的某些行而不是其他行
  • 很公平。可能有可能将您的数据“收集”到整洁的表单,执行操作并使用tidyr 将其“传播”回来。不过,这可能需要我更长的时间才能弄清楚。

标签: r dplyr


【解决方案1】:

tidyverse 解决方案。您将数据收集到一个“整洁”的表格中,在Correct_Answer 上进行有条件的变异,然后将其传播回去。

library(tidyr)
library(dplyr)

qs %>% 
   gather(Resp, val, Response_A:Response_D, -Correct_Answer, -Explanation) %>% select(-val) %>% 
   mutate(Expl = if_else(paste("Response", Correct_Answer, sep="_") == Resp, Explanation, "")) %>%
   spread(Resp, Expl)

希望能解决问题!

【讨论】:

    【解决方案2】:

    一种方法是使用自定义函数,在该行的正确列中分配正确的值

    assignValue <- function(x) {
       qs[x, paste0("Response_", qs$Correct_Answer[x])] <<- qs$Explanation[x]
     }
    

    然后使用sapply为每一行调用函数

    sapply(1:nrow(qs), function(x) assignValue(x))
    

    注意,在函数中使用&lt;&lt;- 运算符。来自帮助页面 (?"&lt;&lt;-")

    > 运算符通常只用在函数中,并导致通过父环境搜索被分配变量的现有定义。如果找到这样的变量(并且其绑定未锁定),则重新定义其值,否则在全局环境中进行赋值

    【讨论】:

      【解决方案3】:

      使用常规的 for 循环可以做到这一点:

      for(i in 1:nrow(qs)){
          qs[i,paste('Response_',qs[i,'Correct_Answer'], sep = '')]=qs[i,'Explanation']
      }
      

      我仍在尝试弄清楚如何使用 sapply 更新 col 值。

      sapply(1:nrow(qs), function(i) qs[paste('Response_',qs[i,'Correct_Answer'], sep = '')]=qs[i,'Explanation'])
      

      【讨论】:

      • 我没有像您在答案中使用的那样使用全局分配。我也认为我的解决方案更简单。
      猜你喜欢
      • 2015-12-06
      • 2018-01-15
      • 1970-01-01
      • 2018-01-03
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      相关资源
      最近更新 更多