IBM® SPSS® 可与 R 通信。就这一点来说,这是一个高度保密的秘密,依据是 R 博客圈的低活动水平。这种有趣的低极性并不奇怪:SPSS 用户通常是仅使用 SPSS 执行其数据分析的人;而 R 用户熟悉在使用 R 的过程中应用聪明的诀窍。想要分析 .sav 格式的数据的 R 用户通常会在 SPSS 中打开该文件,将它保存为逗号分隔值 (CSV) 格式,然后使用 read.csv()
方法在 R 中打开结果。一种更清楚的方式是从 SPSS 保存为 SPSS Statistics Portable (POR) 格式,然后使用来自 foreign
库的 read.spss()
方法打开结果。此方法通常有效,只需几十行 R 代码来处理类别、缺少的值、时间变量和其他在转换过程中丢失或损坏的特性。如果您需要将数据从 R 返回到 SPSS,那么返回旅程更加麻烦。
尽管数据操作很单调,但您肯定不需要插件来连接两个应用程序,就可以使用它们。那么生产力的提升值不值得学习该插件所花的精力?是否能带来生产力提升或一种不同的优势?对于这些问题,答案是肯定的。从一种数据格式转换为另一种总是棘手且耗时。从 SPSS 使用 R 时,您可向 SPSS 数据应用 R 函数,同时保持原始数据库的完整性。从 SPSS 使用 R,您可向 SPSS 数据应用 R 函数,同时保持原始数据库的完整性。
使用 R 集成插件还有一个优势。在 R 和 SPSS 都用在相同的数据上时,R 集成插件的使用可促进可重复性研究。
可重复性研究主要是一种组织原则。给定原始数据文件和语法文件,可以从这两个文件重新创建分析的每一步。几个月后,如果您需要返回到问题中获取更多数据或执行新分析,可以重新构建原始项目。借助 SPSS,您可为在数据上运行的每个过程保留一条记录,无论是转换该数据,创建新变量还是分析。如果 R 在分析中发挥着作用,无论是帮助记录变量还是提供一个 SPSS 中目前没有的函数,在同一个语法文件中同时维护 SPSS 和 R 语法都具有价值。您可从同一个 SPSS 语法文件运行 SPSS 和 R 代码,并将它应用到同一个数据库。每个部分都保持在一起。
回页首
在之前的一篇文章中,我认为数据分析师应学习 R。简言之,统计领域的大多数进步都是首先以 R 包的形式出现的,随后才添加到下拉菜单中。R 为 SPSS 用户提供了更多工具来完成工作,而且尽管您可在 SPSS 外通过导出数据来实现这些工具,但数据导出绝不是无缝的。借助 R 插件,您可保留 SPSS 数据库的所有特性,特别是类别数据的标签和长长的描述符。
回页首
SPSS 允许您创建更多菜单项并将它们添加到现有的菜单栏。具体来讲,R 函数可捆绑为插件并通过菜单提供给您。您无需 R 编程知识,即可在 R 中实现一个函数。扩展的编写不属于本文的介绍范畴,但它们是学习使用 R 插件的重要原因。通过此插件,您可将 R 函数提供给不熟悉 R 的 SPSS 用户。
回页首
该插件的安装非常简单,但过程确实包含一些障碍。一方面,您必须打开多个页面,才能到达实际的下载页面。您需要在 IBM developerWorks 注册(如果还未注册)。它是免费的。
安装过程中的另一个障碍是,该插件仅适用于一个 R 版本,不一定是当前版本。您需要哪个 R 版本,取决于您正在运行的 SPSS 的版本。不幸的是,下载页面没有指明。但是,对于 SPSS 22 版,可使用 R-2.15。对于 SPSS 21 版,可使用 R-2.14.0。
需要注意,R 集成插件是特定于 R 版本的。例如,对于 SPSS 21 版,您必须安装 R-2.14.0。如果安装 2.14.1 或 2.14.2,它将不起作用。在安装过程中,该插件会寻找一个包含正确的 R 版本的文件夹。例如,如果您在 Windows® 上使用 SPSS 21 版,它将寻找 C:/Program Files/R/R-2.14.0。如果安装程序无法找到它想要的文件夹,它会向您询问 R 的位置。通过此询问,您可推断您需要的准确的 R 版本:
如果您已使用一个不同的 R 版本并希望将它保留为默认版本,一定要取消选中 Store version number in registry 复选框。如果您想要安装 R 包来用于 SPSS,您需要从该 SPSS 所使用的 R 版本安装它们。为当前版本下载的 R 包对 R 集成包不可见。
在该页面的中部,单击 SPSS 插件的链接。
SPSS 有许多插件,但选择针对 R 的一个。此链接会将您带到 IBM 下载的登录屏幕。
每个 SPSS 版本都拥有自己的插件。找到适合您的版本的插件,下载它,然后安装它。
在此阶段,如果您没有安装正确的 R 版本,您会看到一条消息表明安装程序无法找到它。请安装一个不同的版本,然后再试一次。
安装该插件后,可从 SPSS 的 Programmability > R plugin 下的 Help 菜单找到此文件。 Working with R 菜单命令现在指向更多文档和教程。
回页首
R 集成插件做两件事:它在 SPSS 和 R 之间建立通信,它为 R 提供一个函数包,并使用该函数包来将 SPSS 数据结构转换为 R 对象。
打开一个语法文件,键入以下行。单击绿色箭头以选择并运行该命令:
BEGIN PROGRAM R. cat("/t/tHello R!/n") END PROGRAM.
行 BEGIN PROGRAM R.
启动 R 并加载必要的数据管理函数库。它也会为 R 设置几个选项变量,这些变量会覆盖您可能在 .First()
函数中设置的任何选项。
这里的第一行和最后一行遵循 SPSS 语法代码的约定,以句点 (.) 结尾。这两行 之间 的所有代码解释为 R 代码,必须遵守 R 语法规则,所以没有句点来标记一行结束。
当 SPSS 处理到 END PROGRAM.
语句时,它将后续命令解释为 SPSS 语法,但它不会退出 R 会话。一个 R 代码块创建的所有变量可在 SPSS 会话期间用于后续 R 代码块。
回页首
从 SPSS 调用的 R 代码块可通过平常的方式从外部来源读取和写入数据。但是如果您从 SPSS 运行 R,这肯定是因为您想访问一个 SPSS 数据库。我创建了一个简单的测试数据库来演示不同的数据类型,该数据库可下载获得。考虑清单 1中的代码。
清单 1. 读取和写入一个数据库
BEGIN PROGRAM R. # Pull the data into a data frame testData = spssdata.GetDataFromSPSS() # Pull the data dictionary into another data frame testDict = spssdictionary.GetDictionaryFromSPSS() # Take a look print(testData) print(testDict) # Check what data types the variables of the R data frame have lapply(testData, class) # Set up a new SPSS database with the same dictionary spssdictionary.SetDictionaryToSPSS("Test2",testDict) # Copy the data to the new SPSS database spssdata.SetDataToSPSS("Test2", testData) # Tell SPSS you're done creating data spssdictionary.EndDataStep() END PROGRAM.
运行此代码时,清单 2中的输出应显示在一个 SPSS 输出文件中。
清单 2. 读取和写入一个数据库的输出
CustName Age Rating Date Weight 1 Mary 21 1 13594608000 55.2 2 John 45 3 13594694400 73.4 3 Henry 33 2 13563244800 80.0 X1 X2 X3 X4 X5 varName CustName Age Rating Date Weight varLabel Customer Name Age Customer rating Date of first trans Weight varType 20 0 0 0 0 varFormat A20 F8 F6 ADATE10 F5.1 varMeasurementLevel nominal scale ordinal scale scale $CustName [1] "factor" $Age [1] "numeric" $Rating [1] "numeric" $Date [1] "numeric" $Weight [1] "numeric"
SPSS 作为一个数据仓库的不错优势在于您可创建详细的数据字典。您可将其中一些信息 —变量类型和名称— 作为类和变量名存储在一个 R 数据框架中,而不会损失细节。R 集成插件支持从活动的 SPSS 数据集创建两个数据框架:一个用于数据,一个用户数据字典。
从测试数据库依次查看每个变量,看看在读入 R 时发生了什么:
CustName
。 此变量是 SPSS 中一个长度为 20 的字符串变量,具有名词类型。它在 R 中变成了一个因子 (factor)。 Age
。 此变量是 SPSS 中一个长度为 6 的非小数数字,具有标量类型。它在 R 中变成了数字。 Rating
。 此变量是一个序数类型的数字。在 SPSS 中为这些数字编码提供了在转换中丢失的描述性标签(有关类别数据的更多信息,请参阅使用类别)。 Date
。 此变量是一个日期,格式为 dd-mmm-yyyy 。它在 R 中变成了数字(有关日期的更多信息,请参阅使用日期)。 Weight
。 一个在 SPSS 中格式化为拥有一位小数的数字变量。它在 R 中变成了数字。 数据字典可导入到 R 中的一个数据框架中,如清单 1所示。您不需要此字典即可在 R 中处理数据,但您需要构建一个数据字典才能创建 SPSS 数据库。数据字典是一个包含字符矢量的数据框架。SPSS 数据库的每个变量对应于它的一列,字典中的每个条目对应于一行。从清单 2中的示例可以看到,有许多格式类型可用。R 插件的文档中提供了完整列表。
回页首
历史上的这一天实际上没有发生什么大事。由于认识到这一天比他想象的更晚,罗马教皇格列高利十三世宣布 1582 年 10 月 5 日的下一天为 10 月 15 日。这一更改(对闰年进行了一定的调整)是罗马教皇格列高利对日历的改良。SPSS 将日期存储为从 1582 年 10 月 10 日午夜开始所经历的秒数,这是公历名义上的起点。R 将日期存储为从 1970 年 1 月 1 日开始所经历的秒数。
R 集成函数 spssdictionary.GetDictionaryFromSPSS()
(没有参数)将日期转换为数字。您获得的数字是从 1582 年 10 月 10 日午夜开始所经历的秒数。
为了转换日期变量以用在 R 中,我可添加 testData$Date = as.POSIXlt(testData$Date, origin="1582-10-10")
。也可利用 GetDataFromSPSS()
函数的一个有用的参数(参见清单 3)。
清单 3. 将日期从 SPSS 读入 R 中
BEGIN PROGRAM R. # Pull the data into a data frame adjusting for dates testData = spssdata.GetDataFromSPSS(rDate="POSIXct") testDict = spssdictionary.GetDictionaryFromSPSS() print(testData) END PROGRAM. CustName Age Rating Date Weight 1 Mary 21 1 2013-07-31 55.2 2 John 45 3 2013-08-01 73.4
清单 4中的示例展示了如何将日期-时间数据从 R 写回到 SPSS 中。文件 IBM.csv 包含从 Yahoo.com 上著名的金融网站获取的 IBM 证券的 NYSE 证券市场数据的一条记录。在这里,您可以看到从 2013 年 8 月 8 日读回的前几行数据。
清单 4. 将日期从 R 写入 SPSS
Date Open High Low Close Volume Adj Close 28/08/2013 182.68 183.47 181.1 182.16 3979200 182.16 27/08/2013 183.63 184.5 182.57 182.74 3179300 182.74 26/08/2013 185.27 187 184.68 184.74 2170400 184.74 23/08/2013 185.34 185.74 184.57 185.42 2292700 185.42 22/08/2013 185.65 186.25 184.25 185.19 2354300 185.19 21/08/2013 184.67 186.57 184.28 184.86 3551000 184.86
我可将该数据读入到 SPSS 中,但日期格式不是 SPSS 日期-时间向导支持的格式。R 会救援任务!从 SPSS 使用 R 语法,我可从 R 打开该文件,将日期转换为一种合适的格式,然后使用结果创建一个 SPSS 数据。这是操作步骤:
spssdictionary.CreateSPSSDictionary()
函数自动化了构建数据字典的一些特性。格式 DATE11
调用日期格式 28-Aug-2013。 清单 5展示了如何执行这些步骤。
清单 5. 将数据直接读入 R 中并使用它们创建一个 SPSS 数据库
BEGIN PROGRAM R. # Set the working directory setwd("C://Users//Catherine//SPSSWork") # (1) IBM = read.csv("IBM.csv", header=TRUE, stringsAsFactors=FALSE) PosixDate = as.POSIXct(strptime(IBM$Date, format="%d/%m/%Y") , format="d-b-Y",origin="1582-10-10") # (2) IBM.spss = data.frame(Date=PosixDate, IBM[,-1]) head(IBM.spss) # Create the data dictionary (3) IBM.dict = spssdictionary.CreateSPSSDictionary(c("Date","Trading date", "0", "DATE11","scale"), c("Open","Opening price","0","F8.2","scale"), c("High","High price","0","F8.2","scale"), c("Low","Low price","0","F8.2","scale"), c("Close","Closing price","0","F8.2","scale"), c("Volume","Trading volume","0","F8.2","scale"), c("AdjClose","Adjusted closing","0","F8.2","scale") ) # Create the new database (4) spssdictionary.SetDictionaryToSPSS("IBM",IBM.dict) spssdata.SetDataToSPSS("IBM",IBM.spss) spssdictionary.EndDataStep() END PROGRAM.
回页首
我的简单示例没有很好地处理类别变量 Rating
。R 获取了该变量的数字代码,但没有获取该变量可能使用的不同级别的描述性标签: Poor
、 Average
和 Excellent
。
您可对该问题采取一些操作。清单 6中所示的 factorMode
参数导入类别级别,而不是数字值。
清单 6. factorMode 参数
BEGIN PROGRAM R. testData = spssdata.GetDataFromSPSS(rDate="POSIXct", factorMode="labels") testDict = spssdictionary.GetDictionaryFromSPSS() print(testData) END PROGRAM. CustName Age Rating Date Weight 1 Mary 21 Poor 2013-07-31 55.2 2 John 45 Excellent 2013-08-01 73.4 3 Henry 33 Average 2012-08-02 80.0
factorMode
参数依据我想要类别变量的数字代码还是值,为我提供了一种选择。但如果我想要使用类别数据创建一个 SPSS 数据库,我需要更多选择。解决方案就是向数据字典添加另一种结构。清单 7中的示例演示了如何从一个包含因素的 R 数据框架构建一个 SPSS 数据库。
基础 R 捆绑了流行的鸢尾属植物数据集。它是一个包含 4 个数字变量和一个因素(表示 3 种特殊的鸢尾属植物物种之一)的数据框架。为了在 SPSS 中构建一个数据库,我完成了以下步骤:
为鸢尾属植物数据创建一个数据字典。
此字典是一个包含 5 列的数据框架(鸢尾属植物数据集的每个变量一列)。
为该因子创建一个类别字典。
这里的 R 结构很复杂。它是一个长度为 2 的列表。第一个组件包含各个因子的名称。第二个组件是一个嵌套列表。每一项都是一个长度为 2 的列表:一个组件表示数字代码,另一个组件表示它们的标签。
运行代码。
这么做会在 SPSS 中创建一个数据库,但不会将它保存到磁盘。这个活动数据库会保留原样。
清单 7. 为类别数据构建一个字典
BEGIN PROGRAM R. data(iris) head(iris) iris.dict = vector(mode="list", length=5) # Name the columns names(iris.dict) = paste("X", 1:5, sep="") # Fill in the numeric variables for(i in 1:4){ iris.dict[[i]] = c(names(iris)[i],"","0","F3.2","scale") } # # Fill information for the category iris.dict[[5]] = c("Species","Species of Iris","0","F3","nominal") # Square it off and add row names iris.dict = data.frame(iris.dict) row.names(iris.dict) = c("varName","varLabel","varType","varFormat", "varMeasurementLevel") # # Now build the category dictionary iris.cat = vector(mode="list",length=2) names(iris.cat) = c("name","dictionary") iris.cat$name = "Species" # Note that the dictionary is a list of lists # With only one category, the first list has length 1 # The dictionary list contains two lists # iris.cat$dictionary = vector(mode="list", length=1) iris.cat$dictionary[[1]] = list(levels=c(1,2,3), labels=levels(iris$Species)) # # Now build the SPSS database. spssdictionary.SetDictionaryToSPSS("Iris", iris.dict, iris.cat) spssdata.SetDataToSPSS("Iris", iris, iris.cat) spssdictionary.EndDataStep() END PROGRAM.
回页首
R 集成包包含许多函数来实现从 SPSS 向 R 的无缝迁移。例如,SPSS 在定义丢失的值方面具有比 R 更高的灵活性。R 集成包包含管理丢失值的函数,以便在从 SPSS 传递到 R 和反向传递时不会丢失任何信息。另一个重要的特性是创建使用 R 的 SPSS 扩展的能力。可向 Analysis 菜单添加菜单项来使 R 函数可在活动数据集上运行,而无需在语法文件中编写显式代码。通过这种方式,您可向没有 R 知识的用户提供 R 的功能。R 集成包为同时使用 SPSS 和 R 的数据分析师提供了许多优势。
回页首
描述 | 名字 | 大小 |
---|---|---|
本文的示例 R 代码 | R-code-examples.zip | 33KB |