跨数据框将李克特数据转换为数字

Converting Likert Data to Numeric Across A Data Frame

我有一个数据集,其中包含 90 个对李克特项目的响应,我想将其转换为数值。它的结构类似于此处的示例:

q6 <- c("Daily", "Never", "Often", "Very Often", "Daily")
q7 <- c("Never", "Never", "Often", "Often", "Daily")
q23 <- c("Daily", "Often", "Never", "Never", "Neutral")
q17 <- c("Important", "Important", "Very Important", "Neutral", "Not Important")
example <- cbind(q6, q7, q17, q23)

每个问题的回答略有不同,但主要在非常不同意到非常同意、每天到从不、重要到不重要的范围内。对 90 个问题的每个回答都在一个单独的列中(标记为 q1 > q90)。我想为一组响应创建新列,其数值对应于文本响应(强烈同意 (3) 到强烈不同意 (-3),通过中性 (0))。像这样

q6 <- c("Daily", "Never", "Often", "Very Often", "Daily")
n6 <- c(3,-3,1,2,3)
q17 <- c("Important", "Important", "Very Important", "Neutral", "Not Important")
n17 <- c(2,2,3,0,-3)
num_example <- cbind(q6, n6, q17, n17)
num_example

到目前为止,我已经成功使用下面的代码,它生成一个名为 n6 的新变量,该变量与现有 q6 列中的文本响应相匹配,然后我可以使用 cbind 添加到现有数据框中。我的问题是:我如何在 90 个问题的整个数据框架中自动执行此操作,而不必为每个响应 运行 下面的代码(即将 q6 更改为 q7,然后更改为 q8,等等)。

n6 <- ifelse(example$q6=="Daily", 3,
                  ifelse(h16$q6=="",0,
                  ifelse(h16$q6=="Very Often", 2,
                  ifelse(h16$q6=="Often", 1,
                  ifelse(h16$q6=="Neither Rarely nor Often", 0,
                  ifelse(h16$q6=="Rarely", -1,
                  ifelse(h16$q6=="Very Rarely", -2,
                  ifelse(h16$q6=="Never", -3,5
                         ))))))))

如上例所示,q6:q12 列和 q23:30 列的响应范围从“每日”到“从不”,以供进一步参考。列 q17:q22 的回复范围从不重要到非常重要,列 q49:q90 的回复范围从强烈同意到强烈不同意。我正在尝试找到一种更智能的方法 运行 在相关列(例如 q6:12、q23:q30)上生成下面的代码,从而生成一个新的数据框,其数值在名为 n6:n16、n23:30 的列,而不必 运行 下面的代码 90 次!

希望这是对问题的清楚解释。

谢谢。

有更快的方法,但由于您已经完成了所有这些工作,请将当前流程转换为一个函数,然后使用 sapply 遍历所有列:

请注意,我将 q6 更改为 [,x]:

numConvert <- function(x) ifelse(example[,x]=="Daily", 3,
             ifelse(h16[,x]=="",0,
                    ifelse(h16[,x]=="Very Often", 2,
                           ifelse(h16[,x]=="Often", 1,
                                  ifelse(h16[,x]=="Neither Rarely nor Often", 0,
                                         ifelse(h16[,x]=="Rarely", -1,
                                                ifelse(h16[,x]=="Very Rarely", -2,
                                                       ifelse(h16[,x]=="Never", -3,5
                                                       ))))))))

现在该函数接受列名并根据您的规范进行转换。试试看:

h16 <- example
sapply(colnames(example), numConvert)
#      q6 q7 q17 q23
# [1,]  3 -3   5   3
# [2,] -3 -3   5   1
# [3,]  1  1   5  -3
# [4,]  2  1   5  -3
# [5,]  3  3   5   5

编辑

如果您想使用闪亮的新功能,请尝试 case_when dplyr >= 0.5.0:

library(dplyr)
factorise <- function(x) {
  case_when(x %in% c("Daily", "Very Important") ~ 3,
            x %in% c("Very Often", "Important") ~ 2,
            x %in% c("Often") ~ 1,
            x %in% c("Neutral") ~ 0,
            x %in% c("Never", "Not Important") ~ -3)
}

sapply(example, factorise)
#      q6 q7 q17 q23
# [1,]  3 -3   2   3
# [2,] -3 -3   2   1
# [3,]  1  1   3  -3
# [4,]  2  1   0  -3
# [5,]  3  3  -3   0

plyr 包有一个名为 revalue 的函数。 Replace specified values with new values, in a factor or character vector. 可能对这里有帮助...

 require(plyr)
 example2 <- revalue(example, c("Daily"= "3", "Never"= "-3", "Often"= "1",
             "Very Often"= "2", "Important" = "3", "Very Important"= "3",
              "Neutral"= "0", "Not Important"= "-3" ))  

     q6   q7   q17  q23 
[1,] "3"  "-3" "2"  "3" 
[2,] "-3" "-3" "2"  "1" 
[3,] "1"  "1"  "3"  "-3"
[4,] "2"  "1"  "0"  "-3"
[5,] "3"  "3"  "-3" "0" 

数据

q6 <- c("Daily", "Never", "Often", "Very Often", "Daily")
q7 <- c("Never", "Never", "Often", "Often", "Daily")
q23 <- c("Daily", "Often", "Never", "Never", "Neutral")
q17 <- c("Important", "Important", "Very Important", "Neutral", "Not Important")
example <- cbind(q6, q7, q17, q23) 

另外,mapvalues 也有效

 mapvalues(example, from = c("Daily", "Never", "Often", "Very Often",
          ,"Important", "Very Important", "Neutral", "Not Important"),
          to = c(3,2,0,-3,2,3,0,-3))

如果您想使用 base R,我建议使用命名向量来构建查找 table,而不是嵌套多个 ifelsess 例如:

n <- c('Daily'=3, 'Very Often'=2, 'Often'=1, 'Never'=-3)
n[q6]
#Daily      Never      Often Very Often      Daily 
#    3         -3          1          2          3 
n[q7]
#Never Never Often Often Daily 
#   -3    -3     1     1     3