• Archive by category "R语言实践"
  • (Page 20)

Blog Archives

RHadoop培训 之 R基础课

RHadoop实践系列文章,包含了R语言与Hadoop结合进行海量数据分析。Hadoop主要用来存储海量数据,R语言完成MapReduce 算法,用来替代Java的MapReduce实现。有了RHadoop可以让广大的R语言爱好者,有更强大的工具处理大数据1G, 10G, 100G, TB, PB。 由于大数据所带来的单机性能问题,可能会一去不复返了。

RHadoop实践是一套系列文章,主要包括”Hadoop环境搭建”,”RHadoop安装与使用”,R实现MapReduce的协同过滤算法”,”HBase和rhbase的安装与使用”。对于单独的R语言爱好者,Java爱好者,或者Hadoop爱好者来说,同时具备三种语言知识并不容 易。此文虽为入门文章,但R,Java,Hadoop基础知识还是需要大家提前掌握。

关于作者
张丹(Conan), 程序员Java,R,PHP,Javascript
weibo:@Conan_Z
blog: http://blog.fens.me
email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/rhadoop-r-basic/

r-title

前言
覆盖R基础知识,快速上手,RHadoop环境的搭建基础课。

目录

  1. 背景知识
  2. 开发环境
  3. R语法
  4. R基本函数
  5. R的扩展包

1. 背景知识

R起源
R 是一个有着统计分析功能及强大作图功能的软件系统,是由奥克兰大学统计学系的Ross Ihaka和Robert Gentleman 共同创立。由于R 受Becker, Chambers & Wilks 创立的S 和Sussman 的Scheme两种语言的影响,所以R 看起来和S 语言非常相似。

R 是一个世界范围统计工作者共同协作的产物,至2013 年2 月共计近5000 个包可在互联网上自由下载,这些都是各行业数据分析同行的工作结晶。

R的特点

  1. 有效的数据处理和保存机制。
  2. 拥有一整套数组和矩阵的操作运算符。
  3. 一系列连贯而又完整的数据分析中间工具。
  4. 图形统计可以对数据直接进行分析和显示,可用于多种图形设备。
  5. 一种相当完善、简洁和高效的程序设计语言。它包括条件语句、循环语句、用户自定义的递归函数以及输入输出接口。
  6. R语言是彻底面向对象的统计编程语言。
  7. R语言和其它编程语言、数据库之间有很好的接口。
  8. R语言是自由软件,可以放心大胆地使用,但其功能却不比任何其它同类软件差。
  9. R语言具有丰富的网上资源

R的下载和安装
R是一个免费的自由软件,它有UNIX、LINUX、MacOS和WINDOWS版本,都是可以免费下载和使用的,在那儿可以下载到R的安装程序、各种外挂程序和文档。在R的安装程序中只包含了8个基础模块,其他外在模块可以通过CRAN获得。

R的官方网站: http://www.r-project.org/

Linux Ubuntu的R安装


~ sudo vi /etc/apt/sources.list
deb http://mirror.bjtu.edu.cn/cran/bin/linux/ubuntu precise/

~ sudo apt-get update
~ sudo apt-get install r-base-core=2.15.3-1precise0precise1

2. 开发环境

R命令行环境:
r-cmd

R默认的界面环境:
r-gui

RStudio的IDE开发环境: http://www.rstudio.com/
r-studio

3. R语法

R是一种语法非常简单的表达式语言(expression language),大小写敏感。
可以在R 环境下使用的命名字符集依赖于R 所运行的系统和国家(系统的locale 设置),允许数字,字母,“.”,“_”

1). 命名
命名必须以”.”或者字母开头,以”.”开头时第二个字符不允许是数字。

2). 基本命令
基本命令要么是表达式(expressions),要么就是赋值(assignments)。

  • 表达式,命令将被解析,并将结果显示在屏幕上,同时清空该命令所占内存。
  • 赋值,命令将被解,并把值传给变量,但结果不会自动显示在屏幕上。

命令可以被”;”隔开或者另起一行。基本命令可以通过大括弧{},放在一起构成一个复合表达式。

注释:一行中以井号”#”开头
换行:如果一条命令在一行结束的时候在语法上还不完整,换行提示符,默认是+

3). 基本的对象
R创建和控制的实体被称为对象。它们可以是变量,数组,字符串,函数,或者其他通过这些实体定义的一般性的结构。

  • 矩阵(matrix)或者更为一般的数组(array)是多维的广义向量。实际上,它们就是向量,而且可以同时被两个或者更多个索引引用,并且以特有的方式显示出来。
  • 因子(factor)为处理分类数据提供的一种有效方法。
  • 列表(list)是一种泛化(general form)的向量。它没有要求所有元素是同一类型,许多时候它本身就是向量和列表类型。列表为统计计算的结果返回提供了一种便利的方法。
  • 数据框(data frame)是和矩阵类似的一种结构。在数据框中,列可以是不同的对象。可以把数据框看作是一个行表示观测个体并且(可能)同时拥有数值变量和分类变量的`数据矩阵’ 。许多实验数据都可以很好的用数据框描述:处理方式是分类变量而响应值是数值变量。
  • 函数(function)是可以保存在项目工作空间的R 对象。该对象为R 提供了一个简单而又便利的功能扩充方法。见编写你自己的函数

在R会话过程中,对象是通过名字创建和保存的。objects(), ls()可以显示当前会话的对象名字。rm()可以删除对象。

对象持久化
R 会话中创建的所有对象可以永久地保存在一个文件中以便于以后的R 会话调用。在每一次R 会话结束的时候,你可以保存当前所有可用的对象。如果你想这样做,这些对象将会写入当前目录下一个叫.RData的文件中,并且所有在这次会话中用过的命令行都会被保存在.Rhistory 的文件中。当R 再次在同一目录下启动,这些对象将从这个文件中重新导入工作空间。同时,相关的历史命令文件也会被导入。

4). 向量和赋值
向量是由一串有序数值构成的序列

x <- c(10.4, 5.6, 3.1, 6.4, 21.7)

函数c()完成的赋值语句。这里的函数c() 可以有任意多个参数,而它返回的值则是一个把这些参数首尾相连形成的向量。

赋值也可以用函数assign()实现。

assign("x", c(10.4, 5.6, 3.1, 6.4, 21.7))

赋值符<-,->可以看作是该命令一个语义上的缩写。

c(10.4, 5.6, 3.1, 6.4, 21.7) -> x

向量运算
在算术表达式中使用向量将会对该向量的每一个元素都进行同样算术运算。
出现在同一个表达式中的向量最好是长度一致。如果他们的长度不一样,该表达式的值将是一个和其中最长向量等长的向量。
表达式中短的向量会被循环使用以达到最长向量的长度。
对于一个常数就是简单的重复。

v <- 2*x + y + 1

逻辑向量
逻辑向量元素可以被赋予的值,有TRUE,FALSE 和NA 逻辑向量可以由条件式(conditions)产生 temp <- x > 13

字符向量
字符向量就是字符串,可以用双引号和单引号作分割符。

paste():可以把单独的字符连成字符串,可以有任意多的参数。参数中的任何数字都将被显式地强制转换成字符串,而且以同样的方式在终端显示。默认的分隔符是单个的空格符。

修改分隔符换成”“

labs <- paste(c("X","Y"), 1:10, sep="")

索引向量:通过索引值可以选择和修改一个数据集的子集
一个向量的子集元素可以通过向量名后面的方括号中加入索引向量得到。如果一个表达式的结果是向量,则我们可以直接在表达式的末尾方括号中加入索引向量以得到结果向量的子向量.

  • 逻辑向量:索引向量必须和被挑选元素的向量长度一致。向量中对应索引向量元素为TRUE 的元素将会被选中,而那些对应FALSE 的元素则被忽略。
    y <- x[!is.na(x)]
  • 正整数向量:索引向量必须是1, 2, … , length(x)的子向量。索引向量中索引对应的元素将会被选中,并且在结果向量中的次序和索引向量中的次序一致。这种索引向量可以是任意长度的,结果向量的长度和索引向量完全一致。
    x[1:10]
  • 负整数向量:这种索引向量指定被排除的元素而不是包括进来。
    y <- x[-(1:5)]
  • 字符串向量:这可能仅仅用于一个对象可以用names 属性来识别它的元素。名字向量的子向量可以像上面第二条提到的正整数标签一样使用。
    fruit <- c(5, 10, 1, 20) 
    names(fruit) <- c("orange”, “banana”, “apple”, “peach”) 
    lunch <- fruit[c(“apple”,“orange”)]
    
  • 5).运算符
    算术运算符:

     + - * / 

    逻辑运算符:

      <,<=,>,>=,==,!=, &, |, ! 

    数学函数:

    log,exp,sin,cos,tan,sqrt ,max ,min,range,length,sum,prod,var
    
    注:var(x): 等价于sum((x-mean(x))^2)/(length(x)-1)
    

    6). 控制语句
    条件语句:if

    if (expr1 ) expr2 else expr3

    循环控制:for,repeat,while

    for (name in expr1 ) expr2

    其中name 是循环变量,expr1是一个向量表达式,而expr2常常是根据虚拟变量name 而设计的成组表达式。在name 访问expr1所有可以取到的值时,expr2都会运行。

    警告:相比其他程序语言,R代码里面很少使用for(),执行效率很低

    
    repeat expr
    while (condition) expr
    

    关键字break:可以用于结束任何循环,甚至是非常规的。它是结束repeat 循环的唯一办法。
    关键字next:可以用来结束一次特定的循环,然后直接跳入"下一次"循环。

    7). 生成正则序列
    1:30 语句:等价于向量c(1, 2, …, 29, 30) 30:1 语句:可用来产生一个逆向的数列。
    seq:数列生成中最为常用的工具。seq(1,30,1) rep:把一个数的完整拷贝多次,保持数列顺序req(x,times=5)

    8). 缺损值
    在某些情况下,向量的元素可能有残缺. 当一个元素或者值在统计的时候"不可得到"(not available)或者"值丢失" (missing value),相关位置可能会被保留并且赋予一个特定的值NA。 任何含有NA 数据的运算结果都将是NA。 函数is.na(x)返回一个和x同等长度的向量。它的某个元素值为TRUE 当且仅当x中对应元素是NA。

    z <- c(1:3,NA); ind <- is.na(z)

    第二种"缺损"值,也称为非数值NaN(Not a Number)

    0/0 或 Inf

    9). 对象
    内在属性:模式和长度
    R操作的实体是对象。实数或复数向量,逻辑向量和字符串向量之类的对象属于"原子"型的对象,因为它们的元素都是一样的类型或模式。R的对象类型包括数值型,复数型,逻辑型,字符型,和原生型。向量必须保证它的所有元素是一样的模式。因此任何给定的向量必须明确属于逻辑性,数值型,复数型,字符型或者原生型.

    列表是任何模式的对象的有序序列。列表被认为是一种"递归"结构而不是原子结构,因为它们的元素可以以它们各自的方式单独列出。函数和表达式也是递归结构。

    所有对象都有模式(mode)和长度(length)两个内在属性

    mode(x),length(x)

    外部属性
    attributes(x):给出对象当前定义的非内在属性的列表。
    attr(object, name): 可以用来设置的外部属性。

    z<-c(1:3,NA) 
    attr(z, "name") <- "abc" 
    attributes(z)
    

    对象的类属性
    R里面的所有对象都属于类(class),可以通过函数class(x)查看。
    对于简单的向量,类是对应的模式(mode):"numeric","logical","character" 或者"list"
    其他的类型,像"matrix","array","factor" 和"data.frame" 就可能是其他值。

    10). 因子(factor)
    假定我们有一份来自澳大利亚所有州和行政区的信息样本 以及他们各自所在地的州名。

    state <- c("tas", "sa", "qld", "nsw", "nsw", "nt")

    在字符向量中,"有序"意味着以字母排序的。

    创建因子factor:

    statef <- factor(state)
    statef
    [1] tas sa  qld nsw nsw nt 
    Levels: nsw nt qld sa tas
    

    levels():可以用来得到因子的水平(levels)。

    levels(statef)
    [1] "nsw" "nt"  "qld" "sa"  "tas"
    

    函数tapply()和不规则数组
    为计算样本中每个州的平均收入,我们可以用函数tapply():

    incomes <- c(60, 49, 40, 61, 64, 60)
    incmeans <- tapply(incomes, statef, mean)
    > incmeans
    nsw   nt  qld   sa  tas 
    62.5 60.0 40.0 49.0 60.0
    

    函数tapply() 可以用来处理一个由多个分类因子决定的向量下标组合。例如,我们可能期望通过州名和性别把这税务会计师分类。

    有序因子
    因子的水平是以字母顺序排列的,或者显式地在factor中指定。有时候因子的水平有自己的自然顺序并且这种顺序是有意义的。ordered()就是用来创建这种有序因子, ordered()和factor 基本完全一样。

    大多数情况下,有序和无序因子的唯一差别在于前者显示的时候反应了各水平的顺序。在线性模型拟合的时候,两种因子对应的对照矩阵的意义是完全不同的。

    11). 数组
    数组可以看作是带有多个下标类型相同的元素集合。
    维度向量(dimension vector)是一个正整数向量。如果它的长度为k,那么该数组就是k-维的。

    向量只有在定义了dim属性后才能作为数组在R中使用。
    假定,z是一个含1500个元素的向量

    
        z<-seq(1,1500)
        dim(z) <- c(3,5,100)
        attributes(z)
        $dim
        [1]   3   5 100
    

    对dim 属性的赋值使得该向量成一个3 ×5 ×100 的数组

    数组索引
    数组元素可以通过给定数组名及其后方括号中用逗号隔开的下标访问。可以根据索引数组去给数组中不规则的元素集合赋值或者将数组中特定的元素返回到一个向量中

    array()
    除了用设定一个向量dim 属性的方法来构建数组,它还可直接通过函数array将向量转换得到.

    假定向量h 有24个或更少的数值,那么命令

    h<-seq(1,24)
    Z <- array(h, dim=c(3,4,2))
    #等价操作
    dim(Z) <- c(3,4,2)
    

    向量和数组混合运算

    • 表达式运算是从左到右进行的
    • 短的向量操作数将会被循环使用以达到其他操作数的长度
    • 有且只有短的向量和数组在一起,数组必须有一样的属性dim,否则返回一个错误
    • 向量操作数比矩阵或者数组操作数长时会引起错误
    • 如果数组结构给定,同时也没有关于向量的错误信息和强制转换操作,结果将是一个和它的数组操作数属性dim 一致的数组。

    数组的外积
    数组一个非常重要的运算就是外积运算(outer product)。如果a 和b 是两个数值数组,它们的外积将是这样的一个数组:维度向量通过连接两个操作数的维度向量得到;数据向量则由a的数据向量元素和b的数据向量元素的所有可能乘积得到。外积是通过特别的操作符%o%实现:

    
    ab <- a %o% b
    ab <- outer(a, b, "*")
         [,1] [,2] [,3]
    [1,]    1    2    3
    [2,]    2    4    6
    [3,]    3    6    9
    

    命令中的乘法操作符可以被任意一个双变量函数代替。

    
    x<-c(1,2,3);y<-c(2,3,4)
    f <- function(x, y) cos(y)/(1 + x^2)
    z <- outer(x, y, f)
    

    两个常规向量的外积是一个双下标的数组(就是矩阵,最大秩为1)。

    数组的广义转置
    函数aperm(a, perm) 可以用来重排一个数组a

    
    B <- aperm(z, c(2,1))
    #等价操作
    t(z)
    

    12). 矩阵

    矩阵是一个双下标的数组. R包括许多只对矩阵操作的操作符和函数。例如上面提到的t(X)就是矩阵的转置函数。函数nrow(A) 和ncol(A) 将会分别返回矩阵A 的行数和列数。

    矩阵相乘
    操作符%*% 用于矩阵相乘。
    如果A和B是大小一样的方阵,那么

    A * B

    将是一个对应元素乘积的矩阵,而

    A %*% B

    则是一个矩阵积。如果x 是一个向量,那么

    x %*% A %*% x

    crossprod():可以完成"矢积"运算,也就是说crossprod(X,y) 和t(X) %*% y 等价,而且在运算上更为高效。
    diag():返回以该向量元素为对角元素的对角矩阵。

    性方程和求逆
    求解线性方程组是矩阵乘法的逆运算。当下面的命令运行后,

    b <- A %*% x

    如果仅仅给出A 和b,那么x 就是该线性方程组的根。在R 里面,用命令

    solve(A,b)

    矩阵的逆可以用下面的命令计算,

    solve(A)

    特征值和特征向量
    ev<-eigen(Sm):用来计算矩阵Sm 的特征值和特征向量。这个函数的返回值是一个 含有values 和vectors 两个分量的列表。

    ev <- eigen(Sm)

    ev$values表示Sm 的特征值向量,ev$vec 则是相应特征向量构成的一个矩阵。

    奇异值分解和行列式
    svd(M): 可以把任意一个矩阵M作为一个参数, 且对M 进行奇异值分解。这包括一个和M 列空间一致的正交列U 的矩阵,一个和M 行空间一致的正交列V 的矩阵,以及一个正元素D 的对角矩阵,如M = U %*% D %*% t(V)。D 实际上以对角元素向量的形式返回。svd(M) 的结果是由d, u 和v构成的一个列表。

    如果M 是一个方阵,就不难看出

    absdetM <- prod(svd(M)$d)

    计算M 行列式的绝对值。如果在各种矩阵中都需要这种运算,我们可以把它定义为一个R 函数

    absdet <- function(M) prod(svd(M)$d)

    此后, 我们可以把absdet() 当一个R 函数使用了。R有一个计算行列式的内置函数det和另外一个给出符号和模的函数。

    evals <- eigen(Sm, only.values = TRUE)$values

    cbind()和rbind()构建分块矩阵
    函数cbind() 和rbind():把向量和矩阵拼成一个新的矩阵。cbind() 把矩阵横向合并成一个大矩阵(列方式),而rbind()是纵向合并(行方式)。
    对数组实现连接操作的函数c()
    将一个数组强制转换成简单向量的标准方法是用函数as.vector()。

    vec <- as.vector(X)
    #等价操作
    vec <- c(X)
    

    因子的频率表
    单个因子会把各部分数据分成不同的组。类似的是,一对因子可以实现交叉分组等。函数table() 可以从等长的不同因子中计算出频率表。如果有k 个因子参数,那么结果将是一个k-维的频率分布数组。

    
    statefr <- table(statef) 
    statefr <- tapply(statef, statef, length)
    

    13). 列表(list)
    R的列表是一个以对象的有序集合构成的对象。列表中包含的对象又称为它的分量(components)。分量可以是不同的模式或类型,如一个列表可以同时包括数值向量,逻辑向量,矩阵,复向量,字符数组,函数等等。

    Lst <- list(name="Fred", wife="Mary", no.children=3,child.ages=c(4,7,9))

    分量常常会被编号,并且可以利用这种编号来访问分量。如果列表Lst 有四个分量,这些分量则可以用Lst[[1]], Lst[[2]], Lst[[3]] 和Lst[[4]] 独立访问。因为Lst 是一个列表,所以函数length(Lst) 给出的仅仅是分量的数目. 列表的分量可以被命名,这种情况下可以通过名字访问。

    构建和修改列表
    list():将已有的对象构建成列表。
    Lst[5] <- list(matrix=Mat) 列表连接
    当连接函数c() 的参数中有列表对象时,结果就是一个列表模式的对象。它的分量是那些当作参数的列表。

    list.ABC <- c(list.A, list.B, list.C)

    14). 数据框
    数据框是一个属于data.frame类的列表。

    对于可能属于数据框的列表对象有下面一些限制条件,

    • 分量必须是向量(数值, 字符, 逻辑),因子,数值矩阵,列表或者其他数据框;
    • 矩阵,列表和数据框为新的数据框提供了尽可能多的变量,因为它们各自拥有列,元素或者变量;
    • 数值向量,逻辑值,因子保持原有格式,而字符向量会被强制转换成因子并且它的水平就是向量中出现的独立值;
    • 在数据框中以变量形式出现的向量结构必须长度一致,矩阵结构必须有一样的行数.
    • 数据框常常会被看作是一个由不同模式和属性的列构成的矩阵。

    创建数据框
    可以通过函数data.frame 创建符合上面对列(分量)限制的数据框对象:

    accountants <- data.frame(home=statef, loot=incomes)

    符合数据框限制的列表可被函数as.data.frame() 强制转换成数据框。

    绑定任意的列表
    attach() 是一个泛型函数。它不仅允许搜索路径绑定目录和数据框,而且还可以绑定其他对象。所以任何其他"list" 模式的对象都可以这样绑定:

    attach(any.old.list)

    任何被绑定的东西都可利用detach 通过位置编号或者名字(最好采用名字)去 除绑定。

    管理搜索路径
    search(): 显示当前的搜索路径。它可以用来跟踪已被绑定或者绑定去除的列表和数据框(以及包)。

    search() 
    [1] “.GlobalEnv” “Autoloads” “package:base” 
    

    其中.GlobalEnv 是工作空间

    lentils 被绑定后,我们可以看到

    search() 
    [1] ".GlobalEnv" "lentils" "Autoloads" "package:base"
    ls(2) 
    [1] "u" "v" "w"
    

    ls (或者objects) 可以用来查看搜索路径中任何位置的内容。

    15). 读数据
    大的数据对象常常是从外部文件中读入,而不是在R 对话时用键盘输入的。
    read.table()函数
    为了可以直接读取整个数据框,外部文件常常要求有特定的格式。 第一行可以有该数据框各个变量的名字。 随后的行中第一个条目是行标签,其他条目是各个变量的值。
    scan() 函数
    假定有三个数据向量,长度一致并且要求并行读入。其中,第一个向量是字符模式,另外两个是数值模式,文件是input.dat。第一步是用scan() 以列表的形式读入这三个向量,
    访问内置数据
    R 提供了大约100个内置的数据集(在包datasets 中),其他的包(包括和R捆绑发布的推荐包) 也提供了一些作为例子的数据集。可以用下面的命令查看当前能访问的数据集列表

    data()

    从其他R 包里面导入数据
    为了访问某个特定包的数据,可以使用参数package,例如

    data(package=“rpart”) 
    data(Puromycin, package=“datasets”)
    

    如果一个包已经被library 绑定,那么它的数据集会被自动地加入到R 的搜索路径中去。

    编辑数据
    edit(x):调用数据框和矩阵时,R 会产生一个电子表形式的编辑环境。

    xnew <- edit(xold)

    16) 编写函数
    R语言允许用户创建自己的函数(function)对象,如mean(), var(),postscript() 等等,这些函数都是用R 写的,因此在本质上和用户写的没有差别。

    一个函数是通过下面的语句形式定义的,

    name <- function(args, ...) {}

    其中expression 是一个R 表达式(常常是一个成组表达式),它利用参数argi 计算最终 的结果。该表达式的值就是函数的返回值。 可以在任何地方以name(expr1 , expr2 , …) 的形式调用函数。

    函数定义如下:

    
    twosam <- function(y1, y2) {
        n1 <- length(y1); n2 <- length(y2)
        yb1 <- mean(y1); yb2 <- mean(y2)
        s1 <- var(y1); s2 <- var(y2)
        s <- ((n1-1)*s1 + (n2-1)*s2)/(n1+n2-2)
        tst <- (yb1 - yb2)/sqrt(s*(1/n1 + 1/n2))
        tst
    }
    a<-1:3;b<-5:7
    twosam(a,b)
    

    参数命名和默认值
    和产生正则序列一样,如果被调用函数的参数以"name=object"方式给出,它们可以用任何顺序设置。但是,参数赋值序列可能以未命名的,位置特异性的方式给出,同时也有可能在这些位置特异性的参数后加上命名参数赋值。 因此,如果有下面方式定义的函数fun1

    fun1 <- function(data, data.frame, graph, limit) {}

    … 参数
    一个函数的参数设置可以传递给另外一个函数。这个可以通过给函数增加一个额外的参数来实现。
    举例如plot

    plot
    function (x, y, ...)
    

    在函数中赋值
    注意任何在函数内部的普通赋值都是局部的暂时的,当退出函数时都会丢失。因此函数中的赋值语句X <- qr(X) 不会影响调用该函数的程序赋值情况。 “强赋值"操作符 <<- :如果想在一个函数里面全局赋值或者永久赋值

    
    fscope<-function(){
      a<-1
      b<<-2
      c=3
    }
    

    作用域
    函数内部的变量可以分为三类:形式参数(formal parameters),局部变量(local variables),自由变量(free variables)。

    • 形式参数是出现在函数的参数列表中的变量。它们的值由实际的函数参数绑定形式参数的过程决定的。
    • 局部变量由函数内部表达式的值决定的。既不是形式参数又不是局部变量的变量是自由变量。
    • 自由变量如果被赋值将会变成局部变量
    
    z<-45
    f <- function(x) {
      y <- 2*x
      print(x)
      print(y)
      print(z)
    }
    

    x 是形式参数,y 是局部变量,z 是自由变量。

    定制环境
    可以修改位置初始化文件,并且每个目录都可以有它特有的一个初始化文件。利用函数.First 和.Last。位置初始化文件的路径可以通过环境变量R PROFILE 设置。这个文件包括你每次执行R时一些自动运行的命令。

    类,泛型函数和面向对象
    一个对象的类决定了它会如何被一个泛型函数处理。相反,一个泛型函数由参数自身类的种类来决定完成特定工作或者事务的。如果参数缺乏任何类属性,或者在该问题中有一个不能被任何泛型函数处理的类,泛型函数会有一种默认的处理方式。

    下面的一个例子使这个问题变得清晰。类机制为用户提供了为特定问题设计和编写泛型函数的便利。在众多泛型函数中,plot() 用于图形化显示对象,summary()用于各种类型的概述分析,以及anova() 用于比较统计模型。 能以特定方式处理类的泛型函数的数目非常庞大。

    methods() 得到当前对某个类对象可用的泛型函数列表:

    methods(class="data.frame")

    相反,一个泛型函数可以处理的类同样很多。例如,plot() 有默认的方法和变 量处理对象类"data.frame","density","factor",等等。

    一个完整的列表同样可以通过函数methods():

    methods(plot)

    17) R中的统计模型
    线性模型,对于常规的多重模型拟合,最基本的函数是lm()。

    fm2 <- lm(y ~ x1 + x2, data = production)

    将会拟合y 对x1 和x2 的多重回归模型和一个隐式的截距项

    提取模型信息的泛型函数
    lm() 的返回值是一个模型拟合结果对象;技术上就是属于类"lm” 的一个结果列表。关于拟合模型的信息可以用适合对象类"lm" 的泛型函数显示,提取,图示等等。

    
    add1 coef effects kappa predict residuals alias 
    deviance family labels print step anova drop1 
    formula plot proj summary
    
    • anova(object1 , object2) 比较一个子模型和外部模型,并且产生方差分析表。
    • coef(object) 提取回归系数(矩阵)。全称:coefficients(object).
    • deviance(object) 残差平方和,若有权重可加权。
    • formula(object) 提取模型公式信息。
    • plot(object) 产生四个图,显式残差,拟合值和一些诊断图。
    • predict(object, newdata=data:frame) 提供的数据框必须有同原始变量一样标签的变量。结果是对应于data:frame中决定变量预测值的向量或矩阵。
    • predict.gam(object,newdata=data:frame) predict.gam() 是安全模式的predict()。它可以用于lm, glm和gam 拟合对象。在正交多项式作为原始的基本函数并且增加新数据意味着必须使用不同的原始基本函数。
    • print(object) 简要打印一个对象的内容
    • residuals(object) 提取残差(矩阵),有权重时可加权,省略方式:resid(object)。
    • step(object) 通过增加或者减少模型中的项并且保留层次来选择合适的模型。在逐步搜索过程中,AIC (Akaike信息规范)值最大的模型将会被返回。
    • summary(object) 显示较详细的模型拟合结果

    18). 图形工具
    图形工具是R 环境里面一个非常重要和多用途的组成部分。我们可以用这些图形工具显示各种各样的统计图并且创建一些全新的图。

    图形工具既可交互式使用,也可以批处理使用。在许多情况下,交互式使用是最有效的。打开R 时,它会启动一个图形设备驱动(device driver)。该驱动会打开特定的图形窗口(graphics window)以显示交互式的图片。尽管这些都是自动实现的,了解用于UNIX 系统的X11() 命令和Windows 系统的windows() 命令是非常有用的。一旦设备驱动启动,R 绘图命令可以用来产生统计图或者设计全新的图形显示。

    绘图命令可以分成了三个基本的类:

    • 高级绘图命令: 在图形设备上产生一个新的图区,它可能包括坐标轴,标签,标题等等。
    • 低级画图命令: 会在一个已经存在的图上加上更多的图形元素,如额外的点,线和标签。
    • 交互式图形命令: 允许你交互式地用定点设备(如鼠标)在一个已经存在的图上添加图形信息或者提取图形信息。

    高级绘图命令
    plot(),这是一个泛型函数:产生的图形依赖于第一个参数的类型或者类。 pairs(X),描绘多元数据提供了两个非常有用的函数

    低级图形函数
    高级图形函数不能准确产生你想要的图。低级图形命令可以在当前图上精确增加一些额外信息(如点,线或者文字)。 points(x, y) lines(x, y)

    数学标注
    在某些情况下,在一个图上加上数学符号和公式是非常有用的。在R 里面,这可以通过函数expression 实现,

    text(x, y, expression(paste(bgroup("(", atop(n, x), ")"), p^x, q^{n-x})))

    图像设备输出

    • X11() 用UNIX 类型的系统的X11 桌面系统
    • windows() 用于Windows 系统
    • quartz() 用于MacOS X 系统
    • postscript() 用于PostScript 打印机,或者创建PostScript 文件。
    • pdf() 创建可以插入PDF 文件中PDF 文件
    • png() 创建PNG 位图文件。(不总是有效的:参考它的帮助文件)
    • jpeg() 创建JPEG 位图文件,非常适用于影
      • 19). 包(packages)
        所有的R 函数和数据集是保存在包里面的。只有当一个包被载入时,它的内容才可以被访问。这样做一是为了高效,二是为了帮助包的开发者防止命名和其他代码中的名字冲突。

        library():查看系统中安装的包 library(plyr):加载plyr包 CRAN.packages() 连接因特网,并且允许自动更新和安装包。 search()为了查看当前有那些包载入了

        标准包
        标准包构成R 原代码的一个重要部分。它们包括允许R 工作的的基本函数,和本文档中描述的数据集,标准统计和图形工具。在任何R 的安装版本中,它们都会被自动获得。

        捐献包和CRAN
        世界各地的作者为R 捐献了好几百个包。其中一些包实现了特定的统计方法,另外一些给予数据和硬件的访问接口,其他则作为教科书的补充材料。 可以从CRAN (http://CRAN.R-project.org/ 和它的镜像)和其他一些资源,如Bioconductor (http://www.bioconductor.org/) 下载得到

        命名空间
        包有命名空间(namespaces),并且现在所有基本的和推荐的的包都依赖于包datasets。

        它们允许包的作者隐藏函数和数据,即只允许内部用户使用,它们防止函数在一个用户使用相同名字时被破坏,它们提供了一种访问特定包的某个对象的方法。

        有两个操作符和命名空间相关。 双冒号操作符:: 选择一个特定命名空间得到的函数定义。可以通过base::t 使用,因为它是在包base 中定义的。 三冒号操作符::: 可能会出现在一些R 代码中:它有点像双冒号操作符,但可以访问隐藏对象。

        包常常是包之间依赖的(inter-dependent),载入其中一个可能会引起其他包的自动载入。

        4. R基本函数

        请查看:R参考卡片,点击下载

        5. R的扩展包

        1). plyr (数据处理)
        plyr是一个数据处理的包,可以把大的数据集通过一些条件拆分成小的数据集的功能包。

        数据集baseball(http://www.baseball-databank.org/)
        21,699 records covering 1,288 players, spanning 1871 to 2007

        举例:击球得分:RBI(Run batted in)

        
        install.packages("plyr")
        library(plyr)
        ?baseball
        ddply(baseball, .(lg), c("nrow", "ncol"))
        rbi <- ddply(baseball, .(year), summarise, mean_rbi = mean(rbi, na.rm = TRUE))
        plot(mean_rbi ~ year, type = "l", data = rbi)
        

        rbi-plyr

        2). stringr (字符串处理)
        stringr是一个字符串处理的包,可以方便地进行各种字符串的操作。

        
        install.packages("stringr")
        library(stringr)
        
        fruits <- c("one apple", "two pears", "three bananas")
        str_replace(fruits, "[aeiou]", "-")
        str_replace_all(fruits, "[aeiou]", "-")
        
        str_replace_all(fruits, "([aeiou])", "")
        str_replace_all(fruits, "([aeiou])", "\\1\\1")
        str_replace_all(fruits, "[aeiou]", c("1", "2", "3"))
        str_replace_all(fruits, c("a", "e", "i"), "-")
        

        3). ggplot2 (可视化)
        ggplot2专业级的可视化绘图包

        
        install.packages("ggplot2")
        library(ggplot2)
        g<-ggplot(mtcars, aes(x=factor(cyl), fill=factor(vs)))
        g+geom_bar(position="dodge")
        

        ggplot2

        http://blog.fens.me/rhadoop-r-basic/

        打赏作者

R利剑NoSQL系列文章 之 Cassandra

R利剑NoSQL系列文章,主要介绍通过R语言连接使用nosql数据库。涉及的NoSQL产品,包括Redis,MongoDBHBaseHiveCassandra, Neo4j。希望通过我的介绍让广大的R语言爱好者,有更多的开发选择,做出更多地激动人心的应用。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明:
http://blog.fens.me/nosql-r-cassandra/

rcassandra

第三篇 R利剑Cassandra,分为7个章节。

  1. Cassandra介绍
  2. Cassandra安装
  3. RCassandra安装
  4. RCassandra函数库
  5. RCassandra基本使用操作
  6. RCassandra使用案例
  7. Cassandra的没落

每一章节,都会分为”文字说明部分”和”代码部分”,保持文字说明与代码的连贯性。

1. Cassandra介绍

Apache Cassandra是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集Google BigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身。Facebook于2008将 Cassandra 开源,此后,由于Cassandra良好的可扩放性,被Digg、Twitter等知名Web 2.0网站所采纳,成为了一种流行的分布式结构化数据存储方案。

Cassandra 的名称来源于希腊神话,是特洛伊的一位悲剧性的女先知的名字,因此项目的Logo是一只放光的眼睛。

Cassandra的数据会写入多个节点,来保证数据的可靠性,在一致性、可用性和网络分区耐受能力(CAP)的折衷问题上,Cassandra比较灵活,用户在读取时可以指定要求所有副本一致(高一致性)、读到一个副本即可(高可用性)或是通过选举来确认多数副本一致即可(折衷)。这样,Cassandra可以适用于有节点、网络失效,以及多数据中心的场景。

Cassandra介绍摘自:维基百科(http://zh.wikipedia.org/wiki/Cassandra)

2. Cassandra安装

文字说明部分:
首先环境准备,这里我选择了Linux Ubuntu操作系统12.04的64位服务器版本,大家可以根据自己的使用习惯选择顺手的Linux。

JDK使用SUN官方版本JDK 1.6.0_29,请不要用Linux自带的openjdk。

手动下载并安装Cassandra。

Cassandra配置,需要提前初始化几个目录。

  • data_file_directories:为数据文件目录
  • commitlog_directory:为日志文件目录
  • saved_caches_directory:为缓存文件目录

下面将介绍单节点的安装,集群安装请参考:Cassandra单集群实验2个节点

代码部分:
单节点安装:系统环境 Linux Ubuntu 12.04 LTS 64bit server


~ uname -a
Linux u1 3.5.0-23-generic #35~precise1-Ubuntu SMP Fri Jan 25 17:13:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

~ cat /etc/issue
Ubuntu 12.04.2 LTS \n \l

JDK环境:SUN官方JDK 1.6.0_29


~ java -version

java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)

下载Cassandra并解压


~ wget http://mirrors.tuna.tsinghua.edu.cn/apache/cassandra/1.2.5/apache-cassandra-1.2.5-bin.tar.gz

~ tar xvf apache-cassandra-1.2.5-bin.tar.gz
~ mv apache-cassandra-1.2.5-bin cassandra125
~ mv cassandra125 /home/conan/toolkit/

~ pwd
/home/conan/toolkit

~ ls -l
drwxrwxr-x  9 conan conan 4096 Jun  1 06:10 cassandra125/
drwxr-xr-x 10 conan conan  4096 Apr 23 14:36 jdk16

初始化cassandra


~ cd /home/conan/toolkit/cassandra125

#配置Cassandra数据文件目录
~ vi conf/cassandra.yaml

data_file_directories:
    - /var/lib/cassandra/data
commitlog_directory: /var/lib/cassandra/commitlog
saved_caches_directory: /var/lib/cassandra/saved_caches

目录的介绍:
data_file_directories:为数据文件目录
commitlog_directory:为日志文件目录
saved_caches_directory:为缓存文件目录

确认操作系统中,这几个目录已被创建。
同时确认/var/log/cassandra/目录,对于cassandra是可写的。


~ sudo mkdir -p /var/lib/cassandra/data
~ sudo mkdir -p /var/lib/cassandra/saved_caches
~ sudo mkdir -p /var/lib/cassandra/commitlog
~ sudo mkdir -p /var/log/cassandra/

~ sudo chown -R conan:conan /var/lib/cassandra
~ sudo chown -R conan:conan /var/log/cassandra/

~ ll /var/lib/cassandra
drwxr-xr-x  2 conan conan 4096 Jun  1 06:21 commitlog/
drwxr-xr-x  2 conan conan 4096 Jun  1 06:21 data/
drwxr-xr-x  2 conan conan 4096 Jun  1 06:21 saved_caches/

设置环境变量


~ sudo vi /etc/environment
CASSANDRA_HOME=/home/conan/toolkit/cassandra125

#让变量生效
~ . /etc/environment

#查看环境变量
~ export |grep /home/conan/toolkit/cassandra125
declare -x CASSANDRA_HOME="/home/conan/toolkit/cassandra125"
declare -x OLDPWD="/home/conan/toolkit/cassandra125"
declare -x PWD="/home/conan/toolkit/cassandra125/bin"

启动cassandra


~ bin/cassandra -f
#注:-f参数是绑定到console,不加-f则是后台启动。

~ jps
19971 CassandraDaemon
20440 Jps

打开客户端


~ bin/cassandra-cli

Connected to: "Test Cluster" on 127.0.0.1/9160
Welcome to Cassandra CLI version 1.2.5

Type 'help;' or '?' for help.
Type 'quit;' or 'exit;' to quit.

[default@unknown]

单节的cassandra,我们已经成功能安装好了。

Cassandra的集群安装请参考:Cassandra单集群实验2个节点

3. RCassandra安装

文字说明部分:
R语言的版本请使用2.15.3,下面介绍如何安装R。

首先,增加一个软件源deb http://mirror.bjtu.edu.cn/cran/bin/linux/ubuntu precise/。
更新及指定安装2.15.3-1precise0precise1版本。

启动R程序,安装RCassandra包。

代码部分
测试环境R语言的版本是:2.15.3

安装R语言


~  sudo vi /etc/apt/sources.list
deb http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse
deb-src http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse
deb http://mirrors.163.com/ubuntu/ precise-security universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-security universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-updates universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-proposed universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-proposed universe main multiverse restricted
deb http://mirrors.163.com/ubuntu/ precise-backports universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-backports universe main multiverse restricted
deb-src http://mirrors.163.com/ubuntu/ precise-updates universe main multiverse restricted
deb http://mirror.bjtu.edu.cn/cran/bin/linux/ubuntu precise/

更新apt-get源


~ sudo apt-get update

#声明安装2.15.3的版本
~ sudo apt-get install r-base-core=2.15.3-1precise0precise1

#启动R
~ R
R version 2.15.3 (2013-03-01) -- "Security Blanket"
Copyright (C) 2013 The R Foundation for Statistical Computing
ISBN 3-900051-07-0
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

安装RCassandra


> install.packages('RCassandra')
> library(RCassandra)

4. RCassandra函数库

文字说明部分
列出有的RCassandra支持的函数,只有17个。记得rredis有100个函数,rmongodb有153个函数。相比之下RCassandra太轻量了。

但是这17个函数,并没有覆盖Cassandra的所有操作,就连一些的基本的操作都没有函数支持,要在命令行处理。不知道是什么原因?!希望RCassandra能继续发展,完善没有实现的功能函数。

不支持的常用操作:
创建keyspaces,删除keyspaces
创建列族,删除列族
删除一行
删除一行的某列数据

下面列出了这17个函数,并与Cassandra的命令做了对比说明。

代码部分
共有17个函数


RC.close               RC.insert
RC.cluster.name        RC.login
RC.connect             RC.mget.range
RC.consistency         RC.mutate
RC.describe.keyspace   RC.read.table
RC.describe.keyspaces  RC.use
RC.get                 RC.version
RC.get.range           RC.write.table
RC.get.range.slices

Cassandra和RCassandra的基本操作对比:


#连接到集群
Cassandra: connect 192.168.1.200/9160;
RCassandra: conn<-RC.connect(host="192.168.1.200",port=9160)

#查看当前集群名字
Cassandra: show cluster name;
RCassandra: RC.cluster.name(conn)

#列出当前集群所有keyspaces
Cassandra: show keyspaces;
RCassandra: RC.describe.keyspaces(conn)

#查看DEMO的keyspace
Cassandra: show schema DEMO;
RCassandra: RC.describe.keyspace(conn,'DEMO')

#选择DEMO的keyspace
Cassandra: use DEMO;
RCassandra: RC.use(conn,'DEMO')

#设置一致性级别
Cassandra: consistencylevel as ONE;
RCassandra: RC.consistency(conn,level="one")

#插入数据
Cassandra:set Users[1][name] = scott;
RCassandra:RC.insert(conn,'Users','1', 'name', 'scott')

#插入数据框
Cassandra:NA
RCassandra:RC.write.table(conn, "Users", df)

#读取列族所有数据
Cassandra: list Users;
RCassandra: RC.read.table(conn,"Users")

#读取数据
Cassandra: get Users[1]['name'];
RCassandra:RC.get(conn,'Users','1', c('name'))

#退出连接
Cassandra: exit; quit;
RCassandra: RC.close(conn)

 

5. RCassandra基本使用操作

文字说明部分
介绍RCassandra的基本函数操作,以iris的数据集为例,介绍了如何利用RCassandra操作Cassandra数据库。

代码部分


#安装RCassandra
install.packages('RCassandra')

#加载RCassandra类库
library(RCassandra)

#建立服务器连接
conn<-RC.connect(host="192.168.1.200")

#当前集群的名字(2个节点集群的名字)
RC.cluster.name(conn)
[1] "case1"

#当前协议的版本
RC.version(conn)
[1] "19.36.0"

#列出所有keyspaces配置信息
RC.describe.keyspaces(conn)

#列出叫的DEMO的keyspaces配置信息
RC.describe.keyspace(conn, "DEMO")

#RCassandra是不能创建的列族的,提前通过Cassandra命令创建一个列族
#[default@DEMO] create column family iris;

#插入iris数据
head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

#iris是一个data.frame
RC.write.table(conn, "iris", iris)

attr(,"class")
[1] "CassandraConnection"

#查看第1行,Sepal.Length列和Species的值
RC.get(conn, "iris", "1", c("Sepal.Length", "Species"))
           key  value           ts
1 Sepal.Length    5.1 1.372881e+15
2      Species setosa 1.372881e+15
#注:ts是时间戳

#查看第1行
RC.get.range(conn, "iris", "1")
           key  value           ts
1 Petal.Length    1.4 1.372881e+15
2  Petal.Width    0.2 1.372881e+15
3 Sepal.Length    5.1 1.372881e+15
4  Sepal.Width    3.5 1.372881e+15
5      Species setosa 1.372881e+15

#查看
r <- RC.get.range.slices(conn, "iris")
class(r)
[1] "list"

r[[1]]
           key  value           ts
1 Petal.Length    1.7 1.372881e+15
2  Petal.Width    0.4 1.372881e+15
3 Sepal.Length    5.4 1.372881e+15
4  Sepal.Width    3.9 1.372881e+15
5      Species setosa 1.372881e+15

rk <- RC.get.range.slices(conn, "iris", limit=0)
y <- RC.read.table(conn, "iris")
y <- y[order(as.integer(row.names(y))),]

head(y)
  Petal.Length Petal.Width Sepal.Length Sepal.Width Species
1          1.4         0.2          5.1         3.5  setosa
2          1.4         0.2          4.9         3.0  setosa
3          1.3         0.2          4.7         3.2  setosa
4          1.5         0.2          4.6         3.1  setosa
5          1.4         0.2          5.0         3.6  setosa
6         

不支持的常用操作

  • 创建keyspaces,删除keyspaces
  • 创建列族,删除列族
  • 删除一行
  • 删除一行的某列数据

6. RCassandra使用案例

文字说明部分
通过一个业务需求的例子,加深我们对RCassandra的认识。下面是一个非常简单的业务场景。

业务需求:
1. 创建一个Users列族,包含name,password两列
2. 在已经数据的情况下,有动态增加一个新列age

代码部分
在Cassandra命令行,创建列族Users


[default@DEMO] create column family Users
...     with key_validation_class = 'UTF8Type'
...     and comparator = 'UTF8Type'
...     and default_validation_class = 'UTF8Type';

89a2fb75-f7d0-399e-b017-30a974b19f4a

RCassandra插入数据,包含name,password两列


> df<-data.frame(name=c('a1','a2'),password=c('a1','a2')) > print(df)
  name password
1   a1       a1
2   a2       a2

#插入数据
> RC.write.table(conn, "Users", df)
attr(,"class")
[1] "CassandraConnection"

#查看数据
> RC.read.table(conn,"Users")
     name password
2    a2       a2
1    a1       a1

#新插入: 一行KEY=1234,并增加age列
> RC.insert(conn,'Users','1234', 'name', 'scott')
> RC.insert(conn,'Users','1234', 'password', 'tiger')
> RC.insert(conn,'Users','1234', 'age', '20')

#查看数据
> RC.read.table(conn,"Users")
     age  name password
1234  20 scott    tiger
2     NA    a2       a2
1     NA    a1       a1

#修改: KEY=1的行中,name=a11, age=12
> RC.insert(conn,'Users','1', 'name', 'a11')
> RC.insert(conn,'Users','1', 'age', '12')

#查看数据
> RC.read.table(conn,"Users")
     age  name password
1234  20 scott    tiger
2     NA    a2       a2
1     12   a11       a1

7. Cassandra的没落

越来越多的基于cassandra构建的应用,开始向hbase迁移。

Cassandra的没落,在技术上可能存在的一些原因:

1. 读的性能太慢

无中心的设计,造成读数据时通过逆熵做计算,性能损耗很大,甚至会严重影响服务器运作。

2. 数据同步太慢(最终一致性延迟可能非常大)

由于无中心设计,要靠各节点传递信息。相互发通知告知状态,如果副本集有多份,其中又出现节点有宕机的情况,那么做到数据的一致性,延迟可能非常大,效率也很低的。

3. 用插入和更新代替查询,缺乏灵活性,所有查询都要求提前定义好。

与大多数数据库为读优化不同,Cassandra的写性能理论上是高于读性能的,因此非常适合流式的数据存储,尤其是写负载高于读负载的。与HBase比起来,它的随机访问性能要高很多,但不是很擅长区间扫描,因此可以作为HBase的即时查询缓存,由HBase进行批量的大数据处理,由Cassandra提供随机查询的接口

4. 不支持直接接入hadoop,不能实现MapReduce。

现在大数据的代名词就是hadoop,做为海量数据的框架不支持hadoop及MapReduce,就将被取代。除非Cassandra能够给出其他的定位,或者海量数据解决方案。DataStax公司,正在用Cassandra重够HDFS的文件系统,不知道是否可以成功。

让我期待Cassandra未来的发展吧!

转载请注明:
http://blog.fens.me/nosql-r-cassandra/

打赏作者

解决RHadoop错误:PipeMapRed.waitOutputThreads(): subprocess failed with code 1

RHadoop实践系列文章,包含了R语言与Hadoop结合进行海量数据分析。Hadoop主要用来存储海量数据,R语言完成MapReduce 算法,用来替代Java的MapReduce实现。有了RHadoop可以让广大的R语言爱好者,有更强大的工具处理大数据1G, 10G, 100G, TB, PB。 由于大数据所带来的单机性能问题,可能会一去不复返了。

RHadoop实践是一套系列文章,主要包括”Hadoop环境搭建”,”RHadoop安装与使用”,R实现MapReduce的协同过滤算法”,”HBase和rhbase的安装与使用”。对于单独的R语言爱好者,Java爱好者,或者Hadoop爱好者来说,同时具备三种语言知识并不容 易。此文虽为入门文章,但R,Java,Hadoop基础知识还是需要大家提前掌握。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/rhadoop-rmr2-pipemapred/

rhadoop-pipemapred

前言

一行错误难倒一片同学,今天在准备 统计之都沙龙 的时候,我也遇到相同的错误。就让我来解决一下,在使用rhadoop的rmr2中,经常会遇到的一个错误。

按照 RHadoop实践系列之二:RHadoop安装与使用 rmr2中实例所演示。


> small.ints = to.dfs(1:10)
> mapreduce(input = small.ints, map = function(k, v) cbind(v, v^2))
> from.dfs("/tmp/RtmpWnzxl4/file5deb791fcbd5")

 

文章目录:

  1. rmr2运行错误日志
  2. 定位错误到hadoop日志
  3. 从hadoop入手找解决办法 — 失败
  4. 从rhadoop入手找解决办法 — 成功

 

1. rmr2运行错误日志

R执行的错误日志如下面:

packageJobJar: [/tmp/Rtmpdf7egm/rmr-local-env3cbb70983, /tmp/Rtmpdf7egm/rmr-global-env3cbb654b85fe, /tmp/                        Rtmpdf7egm/rmr-streaming-map3cbba213f2e, /home/conan/hadoop/tmp/hadoop-unjar1697638502297829404/] [] /tmp                        /streamjob4620072667602885650.jar tmpDir=null
13/06/23 10:44:25 INFO mapred.FileInputFormat: Total input paths to process : 1
13/06/23 10:44:25 INFO streaming.StreamJob: getLocalDirs(): [/home/conan/hadoop/tmp/mapred/local]
13/06/23 10:44:25 INFO streaming.StreamJob: Running job: job_201306231032_0001
13/06/23 10:44:25 INFO streaming.StreamJob: To kill this job, run:
13/06/23 10:44:25 INFO streaming.StreamJob: /home/conan/hadoop/hadoop-1.0.3/libexec/../bin/hadoop job  -D                        mapred.job.tracker=hdfs://master:9001 -kill job_201306231032_0001
13/06/23 10:44:25 INFO streaming.StreamJob: Tracking URL: http://master:50030/jobdetails.jsp?jobid=job_20                        1306231032_0001
13/06/23 10:44:26 INFO streaming.StreamJob:  map 0%  reduce 0%
13/06/23 10:45:04 INFO streaming.StreamJob:  map 100%  reduce 100%
13/06/23 10:45:04 INFO streaming.StreamJob: To kill this job, run:
13/06/23 10:45:04 INFO streaming.StreamJob: /home/conan/hadoop/hadoop-1.0.3/libexec/../bin/hadoop job  -Dmapred.job.tracker=hdfs://master:9001 -kill job_201306231032_0001
13/06/23 10:45:04 INFO streaming.StreamJob: Tracking URL: http://master:50030/jobdetails.jsp?jobid=job_201306231032_0001
13/06/23 10:45:04 ERROR streaming.StreamJob: Job not successful. Error: # of failed Map Tasks exceeded allowed limit. FailedCount: 1. LastFailedTask: task_201306231032_0001_m_000000
13/06/23 10:45:04 INFO streaming.StreamJob: killJob...
Streaming Command Failed!
Error in mr(map = map, reduce = reduce, combine = combine, vectorized.reduce,  :
  hadoop streaming failed with error code 1

我们光看上面的日志,根本发现不了hadoop的实际错误是什么!

2. 定位错误到hadoop日志

接下来需要定位到实际错误的位置。为了方便查询日志,我们打开jobtracker的控制台:http://192.168.1.210:50030/jobtracker.jsp
并找到刚才出现错误的, 日志中有提示的网页位置, Tracking URL: http://master:50030/jobdetails.jsp?jobid=job_201306231032_0001

rhadoop

查看map的错误,现在已经明确有了错误定义。


Running a job using hadoop streaming and mrjob: PipeMapRed.waitOutputThreads(): subprocess failed with code 1
java.lang.RuntimeException: PipeMapRed.waitOutputThreads(): subprocess failed with code 1 at 
org.apache.hadoop.streaming.PipeMapRed.waitOutputThreads(PipeMapRed.java:362) at 
org.apache.hadoop.streaming.PipeMapRed.mapRedFinished(PipeMapRed.java:576) at 
org.apache.hadoop.streaming.PipeMapper.close(PipeMapper.java:135) at 
org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:57) at 
org.apache.hadoop.streaming.PipeMapRunner.run(PipeMapRunner.java:36) at 
org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:436) at 
org.apache.hadoop.mapred.MapTask.run(MapTask.java:372) at 
org.apache.hadoop.mapred.Child$4.run(Child.java:255) at 
java.security.AccessController.doPrivileged(Native Method) at 
javax.security.auth.Subject.doAs(Subject.java:396) at 
org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1121) at 
org.apache.hadoop.mapred.Child.main(Child.java:249)

3. 从hadoop入手找解决办法 — 失败

查看hadoop错误列表:code 1的错误
“OS error code 1: Operation not permitted”"OS error code 2: No such file or directory”

我来分析一下:hadoop和R的用户和用户组

启动hadoop, 用户conan, 用户组conan
启动R, 用户conan, 用户组conan

既然都是相同权限的用户,怎么会有权限的问题呢。

再找另一个hadoop环境做测试,用户使用root,没有错误如文章所示,RHadoop实践系列之二:RHadoop安装与使用

好了,这样问题已经很具体了,我们去网上查找一下错误原因。

通过google搜索,找到 org.apache.hadoop.security.AccessControlException解决办法文章
http://www.51testing.com/?uid-445759-action-viewspace-itemid-821244

具体的错误原因,在文章中有写,我就不再列出了。我们参考他的方法二,对我们的hadoop环境进行调整。
在hdfs-site.xml中增加dfs.permissions.superusergroup的定义。

superusergroup,默认值用什么我们可以在系统中查一下。


~ hadoop fs -ls /
drwxr-xr-x   - conan supergroup          0 2013-04-24 01:52 /hbase
drwxr-xr-x   - conan supergroup          0 2013-04-25 04:59 /home
drwxr-xr-x   - conan supergroup          0 2013-06-23 10:44 /tmp
drwxr-xr-x   - conan supergroup          0 2013-04-24 19:28 /user

这样就得到了supergroup的名字是supergroup, 我们修改hdfs-site.xml,增加dfs.permissions.superusergroup的定义


~ vi $HADOOP_HOME/conf/hdfs-site.xml

<configuration>
<property>
<name>dfs.data.dir</name>
<value>/home/conan/hadoop/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.permissions.superusergroup</name>
<value>supergroup</value>
</property>
</configuration>

重启hadoop,重启R程序,重新执行rmr2脚本。还是有错误,没有解决问题。

4. 从rhadoop入手找解决办法 — 成功

我们找到rhadoop的作者github的issue 122:
https://github.com/RevolutionAnalytics/RHadoop/issues/122

发现其他人也遇到了,类似的错误。这issue已经是closed状态,证明错误已经解决。
根据作者的回答我们发现,错误是由于:“R的类库在特定的用户下面,而不是标准合位置,导致类库不能被hadoop找到”。

在我们的环境中,发现也是同样的配置,与错误描述一致。


~ R
> .libPaths()
[1] "/home/conan/R/x86_64-pc-linux-gnu-library/2.15"
[2] "/usr/local/lib/R/site-library"
[3] "/usr/lib/R/site-library"
[4] "/usr/lib/R/library"

~ ls /home/conan/R/x86_64-pc-linux-gnu-library/2.15
colorspace  functional  iterators  munsell  RColorBrewer  rhdfs    rmr2
dichromat   ggplot2     itertools  plyr     Rcpp          rJava    scales
digest      gtable      labeling   proto    reshape2      RJSONIO  stringr

~ ls /usr/local/lib/R/site-library

我们环境安装的所有类库,都在/home/conan目录下面,而/usr/local/lib/R/site-library一个库类都没有。

我们按照rhadoop作者指示,把包进行重新安装。


#切换到root下面
~ sudo -i

#查看R的类库路径
~ R
> .libPaths()
[1] "/usr/local/lib/R/site-library" "/usr/lib/R/site-library"
[3] "/usr/lib/R/library"

#在root下进行安装
~ R CMD javareconf 
~ R

#启动R程序
install.packages("rJava")
install.packages("reshape2")
install.packages("Rcpp")
install.packages("iterators")
install.packages("itertools")
install.packages("digest")
install.packages("RJSONIO")
install.packages("functional")

~ cd /home/conan/R
~ R CMD INSTALL rmr2_2.1.0.tar.gz
~ ls /usr/local/lib/R/site-library
digest  functional  iterators  itertools  plyr  Rcpp  reshape2  rJava  RJSONIO  rmr2  stringr

依赖包都安装在了/usr/local/lib/R/site-library下面,我们退出root用户,重新启动R程序测试


~ exit
~ whoami
conan

~ R
> library(rmr2)
Loading required package: Rcpp
Loading required package: RJSONIO
Loading required package: digest
Loading required package: functional
Loading required package: stringr
Loading required package: plyr
Loading required package: reshape

#再次运行 rmr2程序
> small.ints = to.dfs(1:10)
> mapreduce(input = small.ints, map = function(k, v) cbind(v, v^2))

packageJobJar: [/tmp/RtmpM87JEc/rmr-local-env1c7588ca7ed, /tmp/RtmpM87JEc/rmr-global-env1c77fdcab5f, /tmp                       /RtmpM87JEc/rmr-streaming-map1c76a4ddf6e, /home/conan/hadoop/tmp/hadoop-unjar6992113986427459004/] [] /tm                       p/streamjob2762947354578034435.jar tmpDir=null
13/06/23 13:27:36 INFO mapred.FileInputFormat: Total input paths to process : 1
13/06/23 13:27:36 INFO streaming.StreamJob: getLocalDirs(): [/home/conan/hadoop/tmp/mapred/local]
13/06/23 13:27:36 INFO streaming.StreamJob: Running job: job_201306231141_0007
13/06/23 13:27:36 INFO streaming.StreamJob: To kill this job, run:
13/06/23 13:27:36 INFO streaming.StreamJob: /home/conan/hadoop/hadoop-1.0.3/libexec/../bin/hadoop job  -D                       mapred.job.tracker=hdfs://master:9001 -kill job_201306231141_0007
13/06/23 13:27:36 INFO streaming.StreamJob: Tracking URL: http://master:50030/jobdetails.jsp?jobid=job_20                       1306231141_0007
13/06/23 13:27:37 INFO streaming.StreamJob:  map 0%  reduce 0%
13/06/23 13:27:51 INFO streaming.StreamJob:  map 100%  reduce 0%
13/06/23 13:27:58 INFO streaming.StreamJob:  map 100%  reduce 100%
13/06/23 13:27:58 INFO streaming.StreamJob: Job complete: job_201306231141_0007
13/06/23 13:27:58 INFO streaming.StreamJob: Output: /tmp/RtmpM87JEc/file1c722c5c6ae

执行成功, 错误解决!!

本文从发现错误,定位错误,查找错误,解决错误,4个步骤解决上面的问题。
希望给遇到问题束手无策的同学,不仅提供直接的错误帮助,更有一个思路上的认识,提高自己的动手能力!!

转载请注明出处:
http://blog.fens.me/rhadoop-rmr2-pipemapred/

打赏作者

RHadoop实验 – 统计邮箱出现次数

RHadoop实践系列文章,包含了R语言与Hadoop结合进行海量数据分析。Hadoop主要用来存储海量数据,R语言完成MapReduce 算法,用来替代Java的MapReduce实现。有了RHadoop可以让广大的R语言爱好者,有更强大的工具处理大数据1G, 10G, 100G, TB, PB。 由于大数据所带来的单机性能问题,可能会一去不复返了。

RHadoop实践是一套系列文章,主要包括”Hadoop环境搭建”,”RHadoop安装与使用”,R实现MapReduce的协同过滤算法”,”HBase和rhbase的安装与使用”。对于单独的R语言爱好者,Java爱好者,或者Hadoop爱好者来说,同时具备三种语言知识并不容 易。此文虽为入门文章,但R,Java,Hadoop基础知识还是需要大家提前掌握。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/rhadoop-demo-email/

rhadoop-demo-email

目录

  1. 需求描述
  2. 实验数据
  3. 算法实现

1. 需求描述

基于RHADOOP通过rmr包实现MapReduce算法

  • 1). 计算邮箱域出现了多少次
  • 2). 按次数从大到小排序

例如:
163.com,14
sohu.com,2

2. 实验数据

wolys@21cn.com
zss1984@126.com
294522652@qq.com
simulateboy@163.com
zhoushigang_123@163.com
sirenxing424@126.com
lixinyu23@qq.com
chenlei1201@gmail.com
370433835@qq.com
cxx0409@126.com
viv093@sina.com
q62148830@163.com
65993266@qq.com
summeredison@sohu.com
zhangbao-autumn@163.com
diduo_007@yahoo.com.cn
fxh852@163.com
weiyang1128@163.com
licaijun007@163.com
junhongshouji@126.com
wuxiaohong11111@163.com
fennal@sina.com
li_dao888@163.com
bokil.xu@163.com
362212053@qq.com
youloveyingying@yahoo.cn
boiny@126.com
linlixian200606@126.com
alex126126@126.com
654468252@qq.com
huangdaqiao@yahoo.com.cn
kitty12502@163.com
xl200811@sohu.com
ysjd8@163.com
851627938@qq.com
wubo_1225@163.com
kangtezc@163.com
xiao2018@126.com
121641873@qq.com
296489419@qq.com
beibeilong012@126.com

3. 算法实现

1). 计算邮箱域出现了多少次

把数据上传到HDFS


library(rmr2)
data<-read.table(file="hadoop15.txt")
d0<-to.dfs(keyval(1, data))
from.dfs(d0)

输出:


$key
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[39] 1 1 1
$val
V1
1 wolys@21cn.com
2 zss1984@126.com
3 294522652@qq.com
4 simulateboy@163.com
5 zhoushigang_123@163.com
6 sirenxing424@126.com
7 lixinyu23@qq.com
8 chenlei1201@gmail.com
9 370433835@qq.com
10 cxx0409@126.com
11 viv093@sina.com
12 q62148830@163.com
13 65993266@qq.com
14 summeredison@sohu.com
15 zhangbao-autumn@163.com
16 diduo_007@yahoo.com.cn
17 fxh852@163.com
18 weiyang1128@163.com
19 licaijun007@163.com
20 junhongshouji@126.com
21 wuxiaohong11111@163.com
22 fennal@sina.com
23 li_dao888@163.com
24 bokil.xu@163.com
25 362212053@qq.com
26 youloveyingying@yahoo.cn
27 boiny@126.com
28 linlixian200606@126.com
29 alex126126@126.com
30 654468252@qq.com
31 huangdaqiao@yahoo.com.cn
32 kitty12502@163.com
33 xl200811@sohu.com
34 ysjd8@163.com
35 851627938@qq.com
36 wubo_1225@163.com
37 kangtezc@163.com
38 xiao2018@126.com
39 121641873@qq.com
40 296489419@qq.com
41 beibeilong012@126.com

计算邮箱域出现了多少次


mr<-function(input=d0){
map<-function(k,v){
keyval(word(as.character(v$V1), 2, sep = fixed('@')),1)
}
reduce =function(k, v ) {
keyval(k, sum(v))
}
d1<-mapreduce(input=input,map=map,reduce=reduce,combine=TRUE)
}
d1<-mr(d0)
from.dfs(d1)

输出:

$key
[1] "126.com" "163.com" "21cn.com" "gmail.com" "qq.com"
[6] "sina.com" "sohu.com" "yahoo.cn" "yahoo.com.cn"
$val
[1] 9 14 1 1 9 2 2 1 2

2). 按次数从大到小排序


sort<-function(input=d1){
map<-function(k,v){
keyval(1,data.frame(k,v))
}
reduce<-function(k,v){
v2<-v[order(as.integer(v$v),decreasing=TRUE),]
keyval(1,v2)
}
d2<-mapreduce(input=input,map=map,reduce=reduce,combine=TRUE)
}
d2<-sort(d1)
result<-from.dfs(d2)
result$val

输出:


k v
2 163.com 14
1 126.com 9
5 qq.com 9
6 sina.com 2
7 sohu.com 2
9 yahoo.com.cn 2
3 21cn.com 1
4 gmail.com 1
8 yahoo.cn 1

转载请注明出处:
http://blog.fens.me/rhadoop-demo-email/

打赏作者

R利剑NoSQL系列文章 之 Redis

R利剑NoSQL系列文章,主要介绍通过R语言连接使用nosql数据库。涉及的NoSQL产品,包括Redis,MongoDBHBaseHiveCassandra, Neo4j。希望通过我的介绍让广大的R语言爱好者,有更多的开发选择,做出更多地激动人心的应用。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

由于文章篇幅有限,均跳过NoSQL的安装过程,请自行参考文档安装。

转载请注明:
http://blog.fens.me/nosql-r-redis/

r-nosql-redis

第二篇 R利剑Redis,分为4个章节。

  1. Redis环境准备
  2. rredis函数库
  3. rredis基本使用操作
  4. rredis使用案例

每一章节,都会分为”文字说明部分”和”代码部分”,保持文字说明与代码的连贯性。

第一章 Redis环境准备

文字说明部分:

首先环境准备,这里我选择了Linux Ubuntu操作系统12.04的64位服务器版本,大家可以根据自己的使用习惯选择顺手的Linux。
(more…)