[原]数据科学教程:R语言与NoSQL

介绍

现代化数据科学中的 DataFrame 概念源起R语言,而 Python Pandas 和 Spark DateFrame 都是参考R设计的。不过在实际的网络数据通信中,相似DateFrame这样的格式却并非主流,真正主流的方式实际上是JSON(JavaScript Object Notation),因此讨论如何处理非结构化数据就变得很是有意义了。加之,近年来 Redis、MongoDB、ELK等非结构化数据库的繁荣,MySQL 5.7以后也已经添加了对JSON格式的原生支持(以前能够用blob、longtext等格式存储),非结构化数据更是在数据处理中变得流行。html

本文将从 非结构化数据的转化、处理以及可视化三个方面讨论如何在R中操做非结构化数据。python

数据清洗:JSON、List、DataFrame的三国杀

DataFrame 是R中的结构化数据结构,List 是R中的非结构化数据。JSON、List、DataFrame三者之间的互相转化是数据科学中很是频繁的一类操做。git

在R中有一个很是有意思的现象,那就是处理json时,咱们有三个选择,jsonlite、rjson以及RJSONIO,三者各有特色,有时为了处理一些问题还必须得混合使用。在实际处理字符串中,必定要注意的就是R中字符串的转义问题。好比\\表示\\"表示"等等。我曾经由于Python和R中的双层JSON解析屡次遇到转义符号的问题。具体能够参看官方手册github

jsonlite

jsonlite 是我最经常使用的一个json处理包,由于jsonlite能够一步将 json 转成 dataframe 再 从dataframe 转到 json,在数据处理中能够轻松解决常见的 json转化问题。此外,jsonlite 还完美支持utf-8,在 json 字符串错误时会有明显的错误提示。sql

jsonlite 的劣势是当出现双层 json 时,jsonlite 会将json转成dataframe格式的 list,这直接致使咱们在用 length() 或者 dim() 求内层 JSON 的维度会出现错误。数据库

jsonlite::fromJSON("{\"x\":\"量化投资\",\"y\":\"harryzhu\"}")
$x
[1] "量化投资"

$y
[1] "harryzhu"

rjson

rjson 和 jsonlite最大不一样之处在于,rjson将json转化为一个list,而list是R语言中非结构化数据的事实标准,相似 python 中的 dict,或者 matlab 中的 cell。json

值得注意的是,rjson在json转化中直接保持全部的浮点型数据,而jsonlite和RJSONIO则能够经过参数控制保留若干位小数的精度。segmentfault

rjson::fromJSON("{\"x\":\"1\",\"y\":\"2\"}")
rjson::toJSON(pi)
$x
[1] "1"

$y
[1] 2

[1] "3.14159265358979"
jsonlite::fromJSON(pi,digit=4)
[1] "[ 3.142 ]"

RJSONIO

RJSONIO 容许传入没有转义符号的 JSON 字符串,而且支持将缺失值(NA)直接转成 Null,须要当心的是RJSONIO只支持unicode,若是传入utf-8则会酿成悲剧。api

RJSONIO::fromJSON(RJSONIO::toJSON(c(1,2,NA,4)))
"[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
NULL

[[4]]
[1] 4"

更多细节能够参考 A biased comparsion of JSON packages in R浏览器

数据处理:List 处理

谈到list的处理就不得不谈一谈 rlist包。rlist包是任坤老师贡献到CRAN上的,任坤老师既是一个多产的R Developer (pipeR、formattable做者)也是一名量化投资者,目前在作私募方面的创业。想要学习rlist,咱们能够参考一下任坤老师的演讲:跳出数据框,拥抱非结构化数据官方教程

rlist与高阶函数

rlist 是支持高阶函数表达式的,借鉴了Python、Scala等语言中的MapReduce模型,rlist也为list提供了map、filter、reduce、group、join、search、sort等高级数据操做,熟悉这些操做之后上手sparkR的RDD操做很是有帮助。

示例一:

利用 GitHub API,咱们能够知道Hadley 的原创R语言开源项目中讨论议题数量最多的10个项目是哪些。

library(rlist)
library(pipeR)
# 分页读取数据
repos <-
"https://api.github.com/users/hadley/repos?per_page=100&page=%d" %>>%
sprintf(1:2) %>>%
list.load("json") %>>%
list.ungroup

repos %>>%
list.filter(has_issues, !fork, language == "R") %>>%
list.names(name) %>>%
list.mapv(open_issues) %>>%
list.sort(-.) %>>%
list.take(10)
# dplyr ggplot2 lubridate devtools staticdocs plyr
# 88 72 54 33 32 28
# stringr roxygen3 scales gtable
# 24 22 22 21

示例二:

批量读取非空 csv 文件而且合并成一个 data frame:

"data/" %>>%
list.files("\\.csv", full.names = TRUE) %>>%
list.filter(file.info(.)$size > 0) %>>%
list.map(read.csv(., header = TRUE, stringsAsFactors = FALSE)) %>>%
list.stack

rlist扩展包充分利用了R语言中list对象的特性,定义了一整套函数来帮助用户灵活快速地按要求处理各类非结构化数据,同时结合pipeR包中管道操做符的使用,使R程序更加具备可读性,应用更加人性化。

更多操做

下面是rlist中提供的操做:

分类 函数
映射(Mapping) list.map, list.mapv, list.select, list.iter, list.maps
筛选(Filtering) list.filter, list.find, list.findi, list.first, list.last,list.take, list.skip,list.takeWhile, list.skipWhile, list.is,list.which, list.all, list.any, list.count, list.match
更新(Updating) list.update
排序(Sorting) list.order, list.sort
分组(Grouping) list.group, list.ungroup, list.cases, list.class, list.common,list.table
合并(Joining) list.join, list.merge
搜索(Searching) list.search
数据读写(I/O) list.parse, list.load, list.save, list.serialize,list.unserialize
数据变换 list.append, list.prepend, list.reverse, list.zip, list.rbind,list.cbind, list.stack, list.flatten, list.names, list.sample

非结构化数据可视化

为了方便在R中可视化JSON数据,jsonview将js中的jsonviewer库引入到R中。

咱们能够传入list或者json字符串作非结构化数据的可视化。

library(xmlview)
library(jsonlite)
devtools::install_github("hrbrmstr/jsonview")
jsonview::json_tree_view(fromJSON("https://collector.torproject.org/index.json"))

下面是timelyportfolio提供的一个结合shiny和jsonview的json编辑器的例子:

install.packages("shiny")
devtools::install_github("timelyportfolio/listviewer")
library(shiny)
library(listviewer)

# 数据准备
data(mtcars)

ui <- shinyUI(
  fluidPage(
    jsoneditOutput( "jsed" )
  )
)

server <- function(input,output){
  output$jsed <- renderJsonedit({
    jsonedit(
      as.list( .GlobalEnv )
      ,"change" = htmlwidgets::JS('function(){
        console.log( event.currentTarget.parentNode.editor.get() )
      }')
    )

  })
}

runApp( list( ui = ui, server = server ) )

接着,在浏览器中的对应端口能够打开这个json编辑器应用。

尾注

除了JSON以外,和NoSQL数据库的交互在大数据时代也成为了主流,混合使用Redis、Hive、MongoDB等数据库也成了屡见不鲜,具体操做能够翻看张丹老师的R利剑NoSQL系列文章

参考资料

做为分享主义者(sharism),本人全部互联网发布的图文均听从CC版权,转载请保留做者信息并注明做者 Harry Zhu 的 FinanceR 专栏: https://segmentfault.com/blog...,若是涉及源代码请注明GitHub地址: https://github.com/harryprince。微信号: harryzhustudio 商业使用请联系做者。
相关文章
相关标签/搜索