文本文件在R中的读写

本文主要讲述的普通文本文件、HTML文件和JSON文件在R中的读写。

普通文本文件的读写

所谓普通文本文件,主要是指由字符组成的文件。它的读写主要使用到了readLines()和writeLines()函数。这两个函数本身非常基础。需要强调的是,readLines()函数会把每行作为字符向量的一个元素(即’\n’为分隔符)读入,所以读入文件常会弹出类似的警告“Warning message: In readLines(“example1.txt”) : incomplete final line found on ‘example1.txt’“,这个不会影响结果。同样,writeLines()函数会把字符向量的每个元素作为一行写出,所以写出的文件常比R中的向量多一个空白行。

HTML文件的读写

HTML文件

HTML(超文本标记语言,HyperText Markup Language)是一种用于创建网页的标准标记语言。通过对HTML文件读取可以进一步在R中分析网页上的内容。在R中能读取HTML文件的包很多,这里主要借助rvest包的read_html()函数来实现。使用到的HTML文件来自于豆瓣网电影专题。为了防止豆瓣网构架调整,导致我们不能顺利读取,我们把这个网页放在这里变成永久链接(新的链接只有文字,不够美观,但是方便我们学习)。 无论如何,我们并不用R来编写HTML文件,所以也不牵涉到HTML文件的写出。

HTML文件的读入

library(rvest)
web = read_html('http://xukuang.github.io/blog/images', encoding = 'UTF-8')
web %>% html_nodes('div.tag-list label') %>% html_text() # 该命令执行后,显示一下结果说明运行成功
	#  [1] "\n            热门\n            "    
	#  [2] "\n            最新\n            "    
	#  [3] "\n            经典\n            "    
	#  [4] "\n            可播放\n            "  
	#  [5] "\n            豆瓣高分\n            "
	#  [6] "\n            冷门佳片\n            "
	#  [7] "\n            华语\n            "    
	#  [8] "\n            欧美\n            "    
	#  [9] "\n            韩国\n            "    
	# [10] "\n            日本\n            "    
	# [11] "\n            动作\n            "    
	# [12] "\n            喜剧\n            "    
	# [13] "\n            爱情\n            "    
	# [14] "\n            科幻\n            "    
	# [15] "\n            悬疑\n            "    
	# [16] "\n            恐怖\n            "    
	# [17] "\n            动画\n            "    

对于网页文件,我们当然也可以下载到本地,把函数read_html()中路径更改为文件所在的本地路径来读取。不过,这种方法不常使用。

JSON文件的读写

JSON文件在R中的读写主要使用了rjson包。

JSON

JSON用于描述数据结构,有以下形式存在。

  • 对象(object):一个对象以“{”开始,并以“}”结束,或以“[”开始,并以“]”结束。一个对象包含一系列非排序的名称/值对,每个名称/值对之间使用“,”分区。
  • 名称/值(collection):名称和值之间使用“:”隔开,一般的形式是:
{name:value}

一个名称是一个字符串; 一个值可以是一个字符串,一个数值,一个对象,一个布尔值,一个有序列表,或者一个null值。

  • 值的有序列表(Array):一个或者多个值用“,”分区后,使用“[”,“]”括起来就形成了这样的列表,形如:
[collection, collection]

  • 字符串:以”“括起来的一串字符。
  • 数值:一系列0-9的数字组合,可以为负数或者小数。还可以用“e”或者“E”表示为指数形式。
  • 布尔值:表示为true或者false。

举例

例1

{
    "table1": {
        "time": "130911",
        "data": {
            "code": [
                "TF1312",
                "TF1403",
                "TF1406"
            ],
            "rt_time": [
                130911,
                130911,
                130911
            ]
        }
    },
    "table2": {
        "time": "130911",
        "data": {
            "contract": [
                "TF1312",
                "TF1312",
                "TF1403"
            ],
            "jtid": [
                99,
                65,
                21
            ]
        }
    }
}

例2

[
{
     "text":"This is the text","color":"dark_red","bold":"true","strikethough":"true","clickEvent":
          {"action":"open_url","value":"zh.wikipedia.org"},
     "hoverEvent":
          {"action":"show_text","value":
               {"extra":"something"}
          }
},
{
     "translate":"item.dirt.name","color":"blue","italic":"true"
}
]

JSON文件的读取

JSON在R中就是一个拥有特定格式的字符串。在R中,除了可以通过fromJSON()函数直接读取本地的JSON文件;理论上,R中所有符合JSON格式的字符串向量都可以通过fromJSON()函数被转化为R中的列表。所以,这里我们有两种方法读取JSON文件。我们把上面JSON的两个实例分别保存为example1.json和example2.json来读取。JSON文件的读取主要使用到了。

方法一

通过fromJOSN()函数直接读取JSON文件为列表对象。

library(rjson)
json_data1 <- fromJSON(file ="example1.json")
json_data1
	# $firstName
	# [1] "John"
	# 
	# $lastName
	# [1] "Smith"
	# 
	# $sex
	# [1] "male"
	# 
	# $age
	# [1] 25
	# 
	# $address
	# $address$streetAddress
	# [1] "21 2nd Street"
	# 
	# $address$city
	# [1] "New York"
	# 
	# $address$state
	# [1] "NY"
	# 
	# $address$postalCode
	# [1] "10021"
	# 
	# $phoneNumber
	# $phoneNumber[[1]]
	# $phoneNumber[[1]]$type
	# [1] "home"
	# 
	# $phoneNumber[[1]]$number
	# [1] "212 555-1234"
	# 
	# $phoneNumber[[2]]
	# $phoneNumber[[2]]$type
	# [1] "fax"

	# $phoneNumber[[2]]$number
	# [1] "646 555-4567"
json_data2 <- fromJSON(file ="example2.json")
json_data2

	# [[1]]
	# [[1]]$text
	# [1] "This is the text"
	# 
	# [[1]]$color
	# [1] "dark_red"
	# 
	# [[1]]$bold
	# [1] "true"
	# 
	# [[1]]$strikethough
	# [1] "true"
	# 
	# [[1]]$clickEvent
	# [[1]]$clickEvent$action
	# [1] "open_url"
	# 
	# [[1]]$clickEvent$value
	# [1] "zh.wikipedia.org"
	#  
	# [[1]]$hoverEvent
	# [[1]]$hoverEvent$action
	# [1] "show_text"
	# 
	# [[1]]$hoverEvent$value
	# [[1]]$hoverEvent$value$extra
	# [1] "something"
	#
	# [[2]]
	# [[2]]$translate
	# [1] "item.dirt.name"
	# 
	# [[2]]$color
	# [1] "blue"
	# 
	# [[2]]$italic
	# [1] "true"

这里原JSON,除最内层都被解析为R的list类型,最内层则是向量类型。这种方法,适合直接读取本地JSON文件。

方法二

先通过readLines()函数读取JSON文件为字符向量,再通过fromJSON()函数转化为列表对象。

json_data1 <- fromJSON(paste(readLines("example1.json"), collapse=""))
json_data2 <- fromJSON(paste(readLines("example2.json"), collapse=""))

这种方法,适合于对R中符合JSON格式的字符向量的处理。由于网页的数据中常包含JOSN格式字符串,所以第二种方法在网页处理中比较好用。

R对象转化为JSON

toJSON()函数可以把R对象序列化为JSON串,以刚才的json_data2为例。

json_str<-toJSON(json_data2)
json_str
	# [1] "[{\"text\":\"This is the text\",\"color\":\"dark_red\",\"bold\":\"true\",\"strikethough\":\"true\",\"clickEvent\":{\"action\":\"open_url\",\"value\":\"zh.wikipedia.org\"},\"hoverEvent\":{\"action\":\"show_text\",\"value\":{\"extra\":\"something\"}}},{\"translate\":\"item.dirt.name\",\"color\":\"blue\",\"italic\":\"true\"}]"
cat(json_str)
	# [{"text":"This is the text","color":"dark_red","bold":"true","strikethough":"true","clickEvent":{"action":"open_url","value":"zh.wikipedia.org"},"hoverEvent":{"action":"show_text","value":{"extra":"something"}}},{"translate":"item.dirt.name","color":"blue","italic":"true"}]

R中一般的输出结果是带转义的输出(\”),用cat输出是标准的JSON串格式。

JSON输出到文件

writeLines(json_str1, "result1.json")
writeLines(json_str2, "result2.json")

举例

一个批量处理JSON文件的例子,数据为data.JSON

library(rjson)

fdlist <- fromJSON(file = 'data.JSON')
fdlist

fdm <- matrix(unlist(fdlist),ncol=4,byrow=T)
fddf <- data.frame(fdm)
head(fddf)

- - - - - -

参考文章:

  1. 维基百科:JSON
  2. R和JSON的傻瓜式编程
  3. 用R获取flash中的数据
Previous     Next Xu Kuang /
Published under (CC) BY-NC-SA in categories 技术篇  tagged with R