5

我有一些数据,我正在尝试将其加载到R中。它位于 .csv 文件中,我可以在 Excel 和 OpenOffice 中查看数据。(如果您好奇,这里是来自加拿大选举局数据的 2011 年民意调查结果数据)。

数据以不寻常​​的方式编码。一个典型的线路是:

12002,Central Nova","Nova-Centre"," 1","River John",N,N,"",1,299,"Chisholm","","Matthew","Green Party","Parti Vert",N,N,11

Central-Nova 的末尾有一个",但开头没有。因此,为了读取数据,我取消了引号,这对于前几个文件效果很好。IE。

test<-read.csv("pollresults_resultatsbureau11001.csv",header = TRUE,sep=",",fileEncoding="latin1",as.is=TRUE,quote="")

现在问题来了:在另一个文件中(例如 pollresults_resultatsbureau12002.csv),有这样一行数据:

12002,Central Nova","Nova-Centre"," 6-1","Pictou, Subd. A",N,N,"",0,168,"Parker","","David K.","NDP-New Democratic Party","NPD-Nouveau Parti democratique",N,N,28

因为我需要取消引号,所以该条目"Pictou, Subd. A"使R想要将其拆分为 2 个变量。无法读取数据,因为它想在构建数据框的中途添加一列。

Excel 和 OpenOffice 都可以打开这些文件没有问题。不知何故,Excel 和 OpenOffice 知道引号只有在变量条目的开头才有意义

你知道我需要在R上启用什么选项来获取这些数据吗?我有超过 300 个文件需要加载(每个文件大约有 1000 行),因此不能选择手动修复...

我到处寻找解决方案,但找不到。

4

2 回答 2

1

该答案主要针对@AnandaMahto(请参阅对原始问题的评论)。

首先,由于数据中的法语口音,它有助于在全局范围内设置一些选项:

options(encoding="latin1")

接下来,使用以下命令逐字读取数据readLines()

temp <- readLines("pollresults_resultatsbureau13001.csv")

在此之后,只需将每行数据中的第一个逗号替换为逗号+引号。这是因为第一个字段总是 5 个字符长。请注意,它使标题保持不变。

temp[-1] <- gsub('^(.{6})(.*)$', '\\1\\"\\2', temp[-1])

倒数第二,覆盖原始文件。

fileConn<-file("pollresults_resultatsbureau13001.csv") writeLines(temp,fileConn) close(fileConn)

最后,只需将数据读回 R:

data<-read.csv(file="pollresults_resultatsbureau13001.csv",header = TRUE,sep=",")

可能有一种更简洁的方法来做到这一点(并且可以更容易地迭代),但这个过程对我来说很有意义。

于 2013-02-26T14:44:35.203 回答
1

基于我的评论,这是一个将所有CSV 文件读入单个列表的解决方案。

# Deal with French properly
options(encoding="latin1")

# Set your working directory to where you have
#   unzipped all of your 308 CSV files
setwd("path/to/unzipped/files")

# Get the file names
temp <- list.files()

# Extract the 5-digit code which we can use as names
Codes <- gsub("pollresults_resultatsbureau|.csv", "", temp)

# Read all the files into a single list named "pollResults"
pollResults <- lapply(seq_along(temp), function(x) {
  T0 <- readLines(temp[x])
  T0[-1] <- gsub('^(.{6})(.*)$', '\\1\\"\\2', T0[-1])
  final <- read.csv(text = T0, header = TRUE)
  final
})
names(pollResults) <- Codes

您可以通过不同方式轻松使用此列表。如果您只想查看第 90 个data.frame,您可以通过 usingpollResults[[90]]或 using pollResults[["24058"]](换句话说,通过索引号或按区号)访问它。

拥有这种格式的数据意味着您还可以做很多其他方便的事情。例如,如果您想一次性修复所有 308 个 CSV,您可以使用以下代码,该代码将创建新的 CSV,其文件名前缀为“Corrected_”。

invisible(lapply(seq_along(pollResults), function(x) {
  NewFilename <- paste("Corrected", temp[x], sep = "_")
  write.csv(pollResults[[x]], file = NewFilename, 
            quote = TRUE, row.names = FALSE)
}))

希望这可以帮助!

于 2013-02-26T16:09:51.323 回答