我最近从Twitter上下载了大量的推文。我的起点是大约400个包含推文ID的.txt文件。在运行工具之后,使用Tweet ID从Twitter上删除推文,并且对于每个.txt文件,我都有大量的推文ID,我得到一个包含JSON字符串的非常大的.txt文件。每个JSON字符串都包含有关Tweet的所有信息。下面是我的单驱动器的超链接,其中包含我正在处理的文件(一旦我开始工作,我将代码应用于其他文件):
https://1drv.ms/t/s!At39YLF-U90fhKAp9tIGJlMlU0qcNQ
我一直在尝试解析每个文件中的每个JSON字符串但没有成功。我的目标是将每个文件转换为R中的大型数据帧。每一行都是Tweet,每列都是Tweet中的一个功能。鉴于它们的性质,“文本”和“#39;列将非常大(它将包含推文的正文),而“#”位置'会很短。每个JSON字符串的格式都相同,每个文件最多可以有一百万个字符串。
我尝试了几种方法(如下所示)来获得我需要的但没有成功的方法:
library('RJSONIO')library('RCurl')
json_file <- fromJSON("Pashawar_test.txt")
json_file2 = RJSONIO::fromJSON(json_file)
错误(函数(classes,fdef,mtable): 无法为签名'&#34;列表&#34;,&#34;缺少&#34;'
找到函数'fromJSON'的继承方法我的另一次尝试:
library('RJSONIO')
json_file <- fromJSON("Pashawar_test.txt")
text <- json_file[['text']]
idstr <- json_file[['id_str']]
此代码似乎只解析文件中的第一个JSON字符串。我之所以这么说,是因为当我试图选择&#39; text&#39;或者&#39; id_str&#39;,我只得到一个实例。还值得指出的是&#39; json_file&#39;是一个大型列表,大小为52.7mb,而源文件为335mb。
答案 0 :(得分:1)
尝试stream_in
包的jsonlite
功能。您的文件包含每行的JSON。您可以逐行阅读并通过fromJSON
进行转换,也可以直接使用stream_in
,这是为了处理这种文件/连接。
require(jsonlite)
filepath<-"path/to/your/file"
#method A: read each line and convert
content<-readLines(filepath)
#this will take a while
res<-lapply(content,fromJSON)
#method B: use stream_in
con<-file(filepath,open="rt")
#this will take a while
res<-stream_in(con)
请注意,stream_in
也会简化结果,将其强制转换为data.frame
,这可能会更加方便。
答案 1 :(得分:1)
这是[n] ewline [d] elimited [json](ndjson)文件,它是为ndjson
包量身定制的。所述包比jsonlite::stream_in()
非常快得多并产生“完全平坦”的数据帧。后一部分(“完全平坦”)不是始终人们真正需要的东西,因为它可以构成一个非常宽的结构(在你的情况下,1,012列,因为它扩展了所有嵌套组件)但你得到你需要什么,而不必自己去除任何东西。
str()
甚至glimpse()
的输出太大而无法在此处显示,但这就是您使用它的方式。
注意我重命名了你的文件,因为.json.gz
通常是如何存储ndjson(我的包可以处理gzip的json文件):
library(ndjson)
library(tidyverse)
twdf <- tbl_df(ndjson::stream_in("~/Desktop/pashwar-test.json.gz"))
## dim(twdf)
## [1] 75008 1012
说完了......
我或者建议使用Apache Drill,因为你有很多这些文件并且它们相对较大。 Drill会让你(最终)将这些转换成镶木地板并显着加快速度,并且有一个与Drill(sergeant
)接口的包:
library(sergeant)
library(tidyverse)
db <- src_drill("dbserver")
twdf <- tbl(db, "dfs.json.`pashwar-test.json.gz`")
glimpse(twdf)
## Observations: 25
## Variables: 28
## $ extended_entities <chr> "{\"media\":[]}", "{\"media\":[]}", "{\"m...
## $ quoted_status <chr> "{\"entities\":{\"hashtags\":[],\"symbols...
## $ in_reply_to_status_id_str <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ in_reply_to_status_id <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ created_at <chr> "Tue Dec 16 10:13:47 +0000 2014", "Tue De...
## $ in_reply_to_user_id_str <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ source <chr> "<a href=\"http://twitter.com/download/an...
## $ retweeted_status <chr> "{\"created_at\":\"Tue Dec 16 09:28:17 +0...
## $ quoted_status_id <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ retweet_count <int> 220, 109, 9, 103, 0, 398, 0, 11, 472, 88,...
## $ retweeted <chr> "false", "false", "false", "false", "fals...
## $ geo <chr> "{\"coordinates\":[]}", "{\"coordinates\"...
## $ is_quote_status <chr> "false", "false", "false", "false", "fals...
## $ in_reply_to_screen_name <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ id_str <dbl> 5.447975e+17, 5.447975e+17, 5.447975e+17,...
## $ in_reply_to_user_id <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ favorite_count <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
## $ id <dbl> 5.447975e+17, 5.447975e+17, 5.447975e+17,...
## $ text <chr> "RT @afneil: Heart-breaking beyond words:...
## $ place <chr> "{\"bounding_box\":{\"coordinates\":[]},\...
## $ lang <chr> "en", "en", "en", "en", "en", "en", "en",...
## $ favorited <chr> "false", "false", "false", "false", "fals...
## $ possibly_sensitive <chr> NA, "false", NA, "false", NA, "false", NA...
## $ coordinates <chr> "{\"coordinates\":[]}", "{\"coordinates\"...
## $ truncated <chr> "false", "false", "false", "false", "fals...
## $ entities <chr> "{\"user_mentions\":[{\"screen_name\":\"a...
## $ quoted_status_id_str <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N...
## $ user <chr> "{\"id\":25968369,\"id_str\":\"25968369\"...
BUT
你已经设法创建了真正不一致的JSON。并非所有具有嵌套内容的字段都以这种方式一致地表示,而Drill的新手会发现制作防弹SQL有些挑战,这将帮助他们在所有场景中消除这些数据。
如果您只需要“已经平坦”位的数据,请尝试钻取。
如果您需要嵌套数据,并且不想与jsonlite::stream_in()
中的取消进行斗争或者在使用Drill forcedsting时遇到困难,那么,我建议使用ndjson
,如第一个示例中所述,然后将你真正需要的部分划分为更易于管理,更整洁的数据框架。