美文网首页
【R】通过R语言进行心理学研究的数据清理

【R】通过R语言进行心理学研究的数据清理

作者: 韦子谦 | 来源:发表于2022-11-06 12:31 被阅读0次

写在前面

为什么要用R进行数据清理?

我大概能想到的:

  • 能方便、快捷地处理大样本数据(几小时甚至几分钟内完成数天的工作);
  • 方便对数据清理过程进行double check(数据清理过程有什么缺漏,可以直接通过看代码文件、跑代码来找出来,修改起来也很方便)以及修改(例如,你想要对另一个dataset进行类似的操作,只需要copy代码然后修改一些内容,无需进行重复的操作);
  • 如果我们知道怎么用R清理数据,那么肯定对R以及数据的内容有了一定的了解,接下来用R进行数据分析也会驾轻就熟

当然,写代码也有缺陷,某些功能的实现其实不如Excel或者SPSS轻松,所以其实不必万事都指望用R来完成。我个人一直推崇“什么方便用什么”,学R就是为了图方便,不要拘泥于一定要全部的数据分析都通过R来完成。

关于本文

我没有经过专业的R语言的训练(例如,没有接触过这方面的workshop或课程),基本上都是边学边做(例如自己从网上找来的或自己琢磨出来的),如果大家有更方便的方法,欢迎交流、分享。

本文假定大家已经有了一定的R基础。

主要针对心理学领域的数据的清理,不过或许也适用于其他研究领域的数据。

数据导入

一些R语言教学书籍或者使用R进行数据分析的文献的supplemental materials会提供数据导入的R代码。但有个问题是,他们使用的R包(package)可能比较旧或者不适用于我们自己的数据格式。

因此,无论是对于新手,还是对于熟悉R代码的老手,个人觉得最稳妥的方式都是通过RStudio的Import Dataset按钮进行数据导入。见下图,如果是txt或者csv格式的数据,可以选择From Text的选项,另外可以导入Excel、SPSS、SAS、Stata的数据。

以Excel格式的数据为例。我们可以通过Data Preview区域查看数据是否正确(例如header是否作为变量名),同时在Code Preview区域还会显示对应的R包和代码,个人推荐大家将这些代码复制到R文件中,这样就不需要每次都点击Import Dataset按钮进行导入,直接跑代码就好。

标注缺省值的方法

可以在导入数据时指定某个特定的值(例如-3)作为缺省值。如果没有在数据导入时这么做,也可以通过以下代码实现。

data[data == -3] = NA

去掉某一个column的方法

如下。

data$itemX <- NULL

计算某个量表的总分或均分

例如某个量表有三道题目(Q01Q02Q03),我们想计算每个被试在这个量表的总分/均分,并记录到QuestionnaireX这一列中。

计算总分:

data$QuestionnaireX <- data$Q01 + data$Q02 + data$Q03

计算均分:

data$QuestionnaireX <- (data$Q01 + data$Q02 + data$Q03)/3

以上两个都是笨方法,但好处是一看便会用。如果题目较多,计算总分可以用rowSums函数,计算均值可以用rowMeans函数。

反向计分

可以通过psych包的reverse.code函数来实现。

例如某个5点量表有三道题目(Q01Q02Q03),其中第二道题应当反向计分。因为是5点量表,所以最小值为1,最大值为5。

代码如下(先取subset,再进行操作)。

data$QuestionnaireX <- subset(data, select=c(Q01, Q02, Q03))
data$QuestionnaireX_new <- reverse.code(keys=c(1,-1,1), data$QuestionnaireX, mini=1, maxi=5)

说明:参数keys用于指定需要反向计分的题目,1表示正向计分,-1表示反向计分。参数minimaxi是指定计分的范围。

对变量进行重新编码其一:cut函数

如下。这个方法也可以用于对测谎题进行编码,并进而依据作答情况筛选被试。

data$newX <- cut(data$itemX, 
                 breaks=c(0, 3,  6, 9),
                 labels=c("low", "medium", "high"))

说明:在这个例子中,我们根据data$itemX的值进行编码,breakslabels的意思就是,如果data$itemX这一列的某个单元格的值在(0, 3],则编码为“low”,如果在(3, 6],则编码为“medium”,如果在(6, 9],则编码为“high”。编码的结果赋值到data$newX这一列中。

对变量进行重新编码其二:mutate函数

来自dplyr包的mutate函数可以将数值编码为二分变量。

例如,某道单选题itemX的选项有1、2、3、4、5,其中1是正确答案,我们想将这道题的值重新编码为1和0,1是回答正确,0是回答错误。代码如下。

data <- data %>% mutate(newX = case_when(itemX == 1 ~ 1, TRUE ~ 0))

说明:这里主要通过一个简单的逻辑判断(if……else……)来对题目进行编码。如果data$itemX的值为1,则编码为1,否则编码为0(TRUE在这里的意思相当于else)。编码的结果赋值到data$newX这一列中。

根据测谎题的情况筛选被试

这里提供我的思路,欢迎交流。

思路一:

data <- data[data$itemLIE1 + data$itemLIE2 + data$itemLIE3 + data$itemLIE4 == 4,]

说明:先将所有测谎题编码为二分变量(1=回答正确,0=错误),然后通过一个简单的逻辑判断来筛选特定的row,例如这里有4道测谎题,所以我筛选了所有四道题都回答正确的被试的row。

也可以设置其他判断要求,例如“>=3”代表筛选回答正确三道题目以上的被试;也可以设置为正确率。

思路2:

如何只保留全部回答正确的被试,也可以用subset函数。

data <- subset(data, itemLIE1 == 1 & itemLIE2 == 1 & itemLIE3 == 1 & itemLIE4 == 1)

注意这里也需要先将测谎题编码为二分变量(1=回答正确,0=错误)。

根据某个特定的题目筛选被试

思路一:我们想找出itemX的回答不为1的被试。可以用subset函数:

data <- subset(data, data$itemX != 1)

思路2:我们想找出itemX的回答为2、3或4的被试。可以用dplyr包的filter函数:

data <- filter(data, itemX %in% c(2, 3, 4))

分组

例如,itemX为分类变量,我们想将其作为分组变了,则可以:

data$groupX <- as.factor(data$groupX)

这样做的好处是你可以立刻通过summary函数来查看每组的人数。

匹配两个dataset的被试

例如,你在做一个纵向研究/追踪研究/队列研究,现在手上有两个time point的数据dataT1dataT2。你希望根据某个独一无二的编号(可能是身份证号、学生/工作证号、被试编号,这里我们称为subID),找出同时完成了两次调查的被试,以便进行后续的分析。

代码如下。

dataT1_matched <- dataT1[dataT1$subID %in% dataT2$subID,]
dataT2_matched <- dataT2[dataT2$subID %in% dataT1$subID,]

筛选后每一行的顺序不一定一一对应(例如某个被试在T1可能在第1行,但在T2可能在第19行),可以通过sort函数基于subID重新排个序。

简单的描述统计其一:快速查看符合特定条件的被试的数量

nrow函数,代码如下。

nrow(data[data$condition1 == "0" & data$condition2 == "0",])

说明:查看data中condition1的值为0且condition2的值也为0的被试的数量。

简单的描述统计其二:连续变量和分类变量的描述统计

可以用一些函数来快速查看你感兴趣的变量的描述统计结果。连续变量用psych包的describe,分类变量用summarytools包的freq函数。另外stargazer等第三方包可以生成很漂亮的描述统计表。具体就不展开了。

数据导出

推荐导出为csv格式的文件。

可以使用tidyverse包的write_excel_csv2()函数来避免中文字符乱码的问题(该函数默认的编码格式为utf-8)。

write_excel_csv(x=data, file="/Users/weiziqian/Desktop/data_test.csv")

注:数据导入、导出过程中的过程中可能出现中文字符乱码的问题,解决问题的关键在于使用正确的函数,并且参数encoding='utf-8'。

 
----------2022.11.09更新----------
添加了反向计分

相关文章

网友评论

      本文标题:【R】通过R语言进行心理学研究的数据清理

      本文链接:https://www.haomeiwen.com/subject/szdportx.html