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

写在前面

为什么要用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更新----------
添加了反向计分

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,126评论 6 520
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,421评论 3 400
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 169,941评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,294评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,295评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,874评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,285评论 3 424
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,249评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,760评论 1 321
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,840评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,973评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,631评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,315评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,797评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,926评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,431评论 3 379
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,982评论 2 361

推荐阅读更多精彩内容