【发布时间】:2018-06-18 02:29:51
【问题描述】:
我正在尝试使用@JD_Long 描述的here 方法从非常大的csv 文件中读取选择数据的有效方法。该方法依赖于同名库中的 sqldf() 函数。我遇到的问题是该函数返回一个空数据框,即具有正确列数及其名称但行数为零的数据框。
一旦数据帧被 sqldf() 读入工作环境,我已经截断了用于处理数据帧的格式化函数。
sum_stats_df <- function(f_name){
# read in data
f <- file(f_name, open = "r")
df <- sqldf("select * from f limit 6", dbname = tempfile(),
file.format = list(header = T, row.names = F))
close(f, type='r')
return(df)
我正在使用的 csv 数据集是我从 ASA 网站 here 下载的著名的交通统计局航班数据。
我尝试了上面链接的 StackOverflow 问题中的示例代码。
bigdf <- data.frame(dim=sample(letters, replace=T, 4e7), fact1=rnorm(4e7), fact2=rnorm(4e7, 20, 50))
write.csv(bigdf, 'bigdf.csv', quote = F)
library(sqldf)
f <- file("bigdf.csv")
bigdf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F))
当我打电话给sum_stats_df("bigdf.csv") 时,它工作得很好。我尝试使用 Windows 文件资源管理器中的属性查看模拟文件和航班 csv 文件的属性,但它们看起来相同的信息。唯一的区别是文件大小。航班文件要大得多,但我不明白这有什么关系。
接下来我尝试使用read.csv(..., nrow=20) 加载其中一个航班 csv 文件的 20 行,然后获取生成的数据帧并将其写回 csv 文件。当我在那个新的 csv 测试文件上尝试有问题的函数时,它起作用了。
> print(head(sum_stats_df("test.csv")))
X Year Month DayofMonth DayOfWeek DepTime CRSDepTime ArrTime CRSArrTime UniqueCarrier
1 "1" 1987 10 14 3 741 730 912 849 "PS"
2 "2" 1987 10 15 4 729 730 903 849 "PS"
3 "3" 1987 10 17 6 741 730 918 849 "PS"
4 "4" 1987 10 18 7 729 730 847 849 "PS"
5 "5" 1987 10 19 1 749 730 922 849 "PS"
6 "6" 1987 10 21 3 728 730 848 849 "PS"
但是,使用原始 csv 文件的调用再次返回一个空数据帧。
> print(head(sum_stats_df("2000.csv")))
[1] Year Month DayofMonth DayOfWeek DepTime
[6] CRSDepTime ArrTime CRSArrTime UniqueCarrier FlightNum
[11] TailNum ActualElapsedTime CRSElapsedTime AirTime ArrDelay
[16] DepDelay Origin Dest Distance TaxiIn
[21] TaxiOut Cancelled CancellationCode Diverted CarrierDelay
[26] WeatherDelay NASDelay SecurityDelay LateAircraftDelay
<0 rows> (or 0-length row.names)
所以我想知道我从 ASA 下载的 csv 文件与我在本地使用 write.csv() 编写的文件有什么不同? sqldf() 返回空数据框但获取所有列名的其他原因可能是什么?
【问题讨论】:
-
我看到的一个问题是您使用
LIMIT而不使用ORDER BY。这没有任何意义,因为您没有告诉数据库如何您希望限制结果集。 你想要哪 6 条记录? -
据我所知,我可能错了,以这种方式使用限制类似于只获取前六行。
-
但我已经无限制地尝试过了,得到了相同的空数据框。
-
请阅读this accepted answer,看看你是否可以在你的函数中打开
file。 -
添加了
l <- readLines(con=f, n=6); print(l)并从文件中获取了标题和五个完整的行。我在这里读过很多答案,说 sql 对象在调用后立即被删除,但它没有解释为什么首先将结果分配给df,也没有解释为什么它适用于本地编写的 csv 文件。