我有两个数据框,一个是调查响应选项(级别),另一个是编码响应。在数据框架中,列具有相同的名称,但不一定是相同的顺序。此外,在级别数据框架内,问题可能有不同数量的响应选项。
levels <- data.frame(restaurant=c("TACO BELL","CHIPOTLE",""),
would_recommend=c("YES","NO",""),
satisfaction=c("VERY SATISFIED","SATISFIED","UNSATISFIED"))
responses <- data.frame(satisfaction=c(2,2,1,1,3,3,2,2),
would_recommend=c(1,2,1,1,2,2,2,1),
restaurant=c(1,2,1,2,1,2,1,2))
响应本质上是其级别在级别表中具有相同名称列的因子,因此我想将它们转换为因子。
我知道我可以通过以下方式做到这一点:
for (i in 1:length(responses)){
resp_levels <- levels[,match(names(responses)[i],names(levels))]
responses[,i]<-factor(x=resp_levels[responses[,i]],levels=resp_levels)
}
如果没有For循环,是否有一种聪明的方法可以做到这一点?
答案 0 :(得分:1)
我普遍同意@gogolews认为for循环没有任何问题,如果它适合你,尤其是像你这样的简单循环。但是,如果您真的需要非循环解决方案,则可以使用包tidyr
和dplyr
的解决方案。对于一个非常庞大的数据集,这可能会更快,但很难肯定地说:
library(dplyr)
library(tidyr)
首先,将响应收集到长格式data.frame中,并添加一个id变量,以便我们知道以后哪些一起使用。我们将因子转换为字符,以便我们可以稍后按名称对其进行索引
new_responses <- responses %>% mutate(id = row_number(restaurant)) %>%
gather(question, response, -id) %>% mutate(question = as.character(question))
现在使用dplyr从级别data.frame中获取适当的级别,然后使用tidyr将其传回简短形式并删除不再需要的id。
responses2 <- new_responses %>% rowwise %>%
mutate(response = as.character(levels[response, question])) %>%
spread(question, response) %>% select(-id)
responses2
Source: local data frame [8 x 3]
restaurant satisfaction would_recommend
1 TACO BELL SATISFIED YES
2 TACO BELL VERY SATISFIED YES
3 TACO BELL UNSATISFIED NO
4 TACO BELL SATISFIED NO
5 CHIPOTLE SATISFIED NO
6 CHIPOTLE VERY SATISFIED YES
7 CHIPOTLE UNSATISFIED NO
8 CHIPOTLE SATISFIED YES
请注意,行不一定与原始行的顺序相同,但可以通过使用id变量来获取新的data.frame。