反向评分项目

15

我有一份大约80项的调查问卷,主要项目具有积极价值(分数越高意味着结果越好),但其中大约20项是负面价值,我需要找到一种在R中对这些负面价值进行反向评分的方法。我完全不知道该如何做。我肯定是R的初学者,这可能是一个愚蠢的问题,但是有人能在代码方面指点一下吗?


什么是“valanced”? - sckott
我只是指高分表示更好的结果(例如1-5 Likert量表;“5”=强烈同意某种说法)。但对于其中一些,Likert量表上的“1”表示强烈同意(这将是负面的价值)。我会反向评分,以便每个项目的高分表示更强的同意程度。@ScottChamberlain - Nick Frost
我是想说“我需要”对它们进行反向评分。 - Nick Frost
1
新来的读者可能希望向下滚动一点,查看基于tidyverse的解决方案。 - Chris Beeley
7个回答

18

这是一个包含虚假数据的示例,您可以根据您自己的数据进行调整:

# Fake data: Three questions answered on a 1 to 5 scale
set.seed(1)
dat = data.frame(Q1=sample(1:5,10,replace=TRUE), 
                 Q2=sample(1:5,10,replace=TRUE),
                 Q3=sample(1:5,10,replace=TRUE))

dat
   Q1 Q2 Q3
1   2  2  5
2   2  1  2
3   3  4  4
4   5  2  1
5   2  4  2
6   5  3  2
7   5  4  1
8   4  5  2
9   4  2  5
10  1  4  2

# Say you want to reverse questions Q1 and Q3
cols = c("Q1", "Q3")

dat[ ,cols] = 6 - dat[ ,cols]

dat
   Q1 Q2 Q3
1   4  2  1
2   4  1  4
3   3  4  2
4   1  2  5
5   4  4  4
6   1  3  4
7   1  4  5
8   2  5  4
9   2  2  1
10  5  4  4
如果您有很多列,可以使用 tidyverse 函数来选择多列进行重编码的单个操作。
library(tidyverse)

# Reverse code columns Q1 and Q3
dat %>% mutate(across(matches("^Q[13]"), ~ 6 - .))

# Reverse code all columns that start with Q followed by one or two digits
dat %>% mutate(across(matches("^Q[0-9]{1,2}"), ~ 6 - .))

# Reverse code columns Q11 through Q20
dat %>% mutate(across(Q11:Q20, ~ 6 - .))

如果不同的列可能有不同的最大值,您可以(根据@HellowWorld的建议)定制每个列的反编码到其最大值:

# Reverse code columns Q11 through Q20 
dat %>% mutate(across(Q11:Q20, ~ max(.) + 1 - .))

非常感谢,这个可以运行并且我能够理解。@eipi10 - Nick Frost
2
对于未来发现此问题的任何人,psych包中有一个名为reverse.code()的函数可以实现此功能。 - Rilcon42
4
用“max(dat[, cols]) + 1”替换6可以扩展代码到其他情况,并防止为一个函数调用加载库。 - HelloWorld

9

这里是一种使用psych包的替代方法。如果您正在处理调查数据,此软件包具有许多良好的功能。在@eipi10的数据基础上构建:

# Fake data: Three questions answered on a 1 to 5 scale
set.seed(1)
original_data = data.frame(Q1=sample(1:5,10,replace=TRUE), 
                 Q2=sample(1:5,10,replace=TRUE),
                 Q3=sample(1:5,10,replace=TRUE))
original_data

# Say you want to reverse questions Q1 and Q3. Set those keys to -1 and Q2 to 1.
# install.packages("psych") # Uncomment this if you haven't installed the psych package
library(psych)
keys <- c(-1,1,-1)

# Use the handy function from the pysch package
# mini is the minimum value and maxi is the maimum value
# mini and maxi can also be vectors if you have different scales
new_data <- reverse.code(keys,original_data,mini=1,maxi=5)
new_data

这种方法的好处是可以在一个函数中重写整个调查。缺点是需要使用库。R语言自带的方法更加优雅。

顺便说一下,这是我在stackoverflow上的第一篇文章。长期听众,第一次提问。所以请给我反馈意见。


8

使用tidyverse将@eipi10的答案进行转换:

# Create same fake data: Three questions answered on a 1 to 5 scale
set.seed(1)
dat <- data.frame(Q1 = sample(1:5,10, replace=TRUE), 
                  Q2 = sample(1:5,10, replace=TRUE),
                  Q3 = sample(1:5,10, replace=TRUE))

# Reverse scores in the desired columns (Q2 and Q3)

dat <- dat %>% 
  mutate(Q2Reversed = 6 - Q2,
         Q3Reversed = 6 - Q3)

4
另一个例子是使用car库中的recode。
 #Example data
 data = data.frame(Q1=sample(1:5,10, replace=TRUE))

 # Say you want to reverse questions Q1
 library(car)
 data$Q1reversed <- recode(data$Q1, "1=5; 2=4; 3=3; 4=2; 5=1")
 data

1

psych包具有直观的reverse.code()函数,可以提供帮助。使用由@eipi10开始的数据集和相同的目标或反转q1和q2:

set.seed(1)
dat <- data.frame(q1 =sample(1:5,10,replace=TRUE), 
                 q2=sample(1:5,10,replace=TRUE),
                 q3 =sample(1:5,10,replace=TRUE))

您可以使用reverse.code()函数。第一个参数是keys,这是一个由1和-1组成的向量。-1表示您想要反转该项。这些按照与您的数据相同的顺序进行。
第二个参数称为items,仅是您数据集的名称。也就是说,这些项目位于哪里?
最后,mini和maxi参数是参与者可能得分的最小值和最大值。您还可以将这些参数留空,函数将使用数据中的最低和最高值。
library(psych)
keys <- c(-1, 1, -1)
dat1 <- reverse.code(keys = keys, items = dat, mini = 1, maxi = 5)

dat1

或者,您的键还可以包含您想要反向评分的变量的特定名称。如果您有许多要反向评分的变量,则这很有帮助,并且会得出相同的答案:

library(psych)
keys <- c("q1", "q3")
dat2 <- reverse.code(keys = keys, items = dat, mini = 1, maxi = 5)

dat2

注意,在反向评分之后,reverse.code() 会略微修改变量名,在其后面加上 -(即,q1 在反向评分后变成 q1-)。

0

这里是另一种通用于任意列数的尝试。让我们使用一些虚构的数据来说明这个函数。

# create a df
{
A = c(3, 3, 3, 3, 3, 3, 3, 3, 3, 3)
B = c(9, 2, 3, 2, 4, 0, 2, 7, 2, 8)
C = c(2, 4, 1, 0, 2, 1, 3, 0, 7, 8)

df1 = data.frame(A, B, C)
print(df1)
}
   A B C
1  3 9 2
2  3 2 4
3  3 3 1
4  3 2 0
5  3 4 2
6  3 0 1
7  3 2 3
8  3 7 0
9  3 2 7
10 3 8 8
要反转代码的列
# variables to reverse code
vtcode = c("A", "B")

反转所选列的函数

reverseCode <- function(data, rev){
  
  # get maximum value per desired col: lapply(data[rev], max)
  # subtract values in cols to reverse-code from max value plus 1
  data[, rev] = mapply("-", lapply(data[rev], max), data[, rev]) + 1
  
  return(data)
  
}


reverseCode(df1, vtcode)

   A  B C
1  1  1 2
2  1  8 4
3  1  7 1
4  1  8 0
5  1  6 2
6  1 10 1
7  1  8 3
8  1  3 0
9  1  8 7
10 1  2 8

这段代码的灵感来自于另一个回答,即@catastrophic-failure关于从列中减去最大值得到列R中所有条目的回答。


0
以上的解决方案假定数据宽格式(每列一个分数)。而这个方法是针对长格式数据中特定行进行反向评分(每行一个分数)。
library(magrittr)
max <- 5
df <- data.frame(score=sample(1:max, 20, replace=TRUE))
df <- mutate(df, question = rownames(df))
df
df[c(4,13,17),] %<>% mutate(score = max + 1 - score)
df

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接