将SPSS数据文件导入R

ste*_*ish 5 r spss

在我的公司,我们正在考虑在选择R时逐步淘汰SPSS.在过渡期间,我们仍将使用SPSS数据文件格式(.sav).

我在将此SPSS数据文件导入R时遇到问题.当我将SPSS文件导入R时,我想保留变量的值和值标签.包中的read.spss()函数foreign使我可以选择保留变量的值或值标签,但不能同时保留两者.

AFAIK,R确实允许因子变量具有值(级别)和值标签(级别标签).我只是想知道是否有可能以某种方式修改read.spss()函数来合并它.

或者,我遇到了spss.system.file()来自memisc包的功能,据说允许这种情况发生,但它要求一个单独的语法文件(codes.file),这对我来说不一定总是可用.

这是一个示例数据文件.

我很感激任何帮助解决这个问题.

谢谢.

djh*_*rio 2

有一种通过ODBC驱动程序读取R中SPSS数据文件的解决方案。

1)有一个IBM SPSS统计数据文件驱动程序。我找不到下载链接。我从我的 SPSS 提供商处获得它。独立驱动程序就是您所需要的。您不需要 SPSS 来安装或使用该驱动程序。

2) 为SPSS数据驱动程序创建DSN。

3)使用RODBC包,您可以在R中读取任何SPSS数据文件。可以将每个变量的值标签作为单独的表获取。然后就可以按照您希望的方式使用 R 中的标签。

这是 Windows 上的一个工作示例(我的计算机上现在没有 SPSS),用于在 R 中读取示例数据文件。我还没有在 Linux 上测试过这个。它可能也适用于 Linux,因为 Linux 也有一个 SPSS 数据驱动程序。

require(RODBC)

# Create connection
# Change the DSN name and CP_CONNECT_STRING according to your setting
con <- odbcDriverConnect("DSN=spss_ehsis;SDSN=SAVDB;HST=C:\\Program Files\\IBM\\SPSS\\StatisticsDataFileDriver\\20\\Standalone\\cfg\\oadm.ini;PRT=StatisticsSAVDriverStandalone;CP_CONNECT_STRING=C:\\temp\\data_expt.sav")

# List of tables
Tables <- sqlTables(con)
Tables

# List of table names to extract
table.names <- Tables$TABLE_NAME[Tables$TABLE_SCHEM != "SYSTEM"]

# Function to query a table by name
sqlQuery.tab.name <- function(table) {
  sqlQuery(con, paste0("SELECT * FROM [", table, "]"))
}

# Retrieve all tables
Data <- lapply(table.names, sqlQuery.tab.name)

# See the data
lapply(Data, head)

# Close connection
close(con)
Run Code Online (Sandbox Code Playgroud)

例如,我们可以为两个变量定义值标签:

[[5]]
  VAR00002 VAR00002_label
1        1           Male
2        2         Female

[[6]]
  VAR00003 VAR00003_label
1        2        Student
2        3       Employed
3        4     Unemployed
Run Code Online (Sandbox Code Playgroud)

附加信息

这是一个允许在连接到 SPSS 数据文件后读取 SPSS 数据的函数。该功能允许指定要选择的变量列表。如果将value.labels=TSPSS数据文件中带有值标签的所选变量转换为带有标签的R因子。

我不得不说我对该解决方案的性能并不满意。它适用于小数据文件。对于大型 SPSS 数据文件(甚至选择了变量子集),经常会达到 RAM 限制。

get.spss <- function(channel, variables = NULL, value.labels = F) {

  VarNames <- sqlQuery(channel = channel,
    query = "SELECT VarName FROM [Variables]", as.is = T)$VarName

  if (is.null(variables)) variables <- VarNames else {
    if (any(!variables %in% VarNames)) stop("Wrong variable names")
  }

  if (value.labels) {
    ValueLabelTableName <- sqlQuery(channel = channel,
      query = "SELECT VarName FROM [Variables]
                                    WHERE ValueLabelTableName is not null",
      as.is = T)$VarName
    ValueLabelTableName <- intersect(variables, ValueLabelTableName)
  }

  variables <- paste(variables, collapse = ", ")

  data <- sqlQuery(channel = channel,
    query = paste("SELECT", variables, "FROM [Cases]"),
    as.is = T)

  if (value.labels) {
    for (var in ValueLabelTableName) {
      VL <- sqlQuery(channel = channel,
        query = paste0("SELECT * FROM [VLVAR", var,"]"),
        as.is = T)
      data[, var] <- factor(data[, var], levels = VL[, 1], labels = VL[, 2])
    }
  }

  return(data)
}
Run Code Online (Sandbox Code Playgroud)