楼主: 一路嘿嘿
1187 0

R中管道操作 [推广有奖]

  • 1关注
  • 1粉丝

已卖:198份资源

硕士生

11%

还不是VIP/贵宾

-

威望
0
论坛币
1594 个
通用积分
3.0756
学术水平
12 点
热心指数
12 点
信用等级
5 点
经验
1054 点
帖子
60
精华
0
在线时间
215 小时
注册时间
2014-6-28
最后登录
2020-8-20

楼主
一路嘿嘿 发表于 2014-12-7 22:27:32 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
很多情况下,管道操作符可以很大程度的简化代码,并且使其更加直观、易读、易懂,下面就简单说明了useR2014上颇受R用户喜爱的magrittr包。

The pipe operator is one (if not THE) most important innovation introduced, this year, to the R ecosystem

Intro
类似于linux中的`|`,可以把前一个表达式(函数)的输出(而不用定义中间变量来表示)
直接传递给后面的函数或者表达式,省去不必要中间变量或者括号,代码更加清晰易读。
magrittr提供了一系列的管道操作符,
如`%>%`,`x %>% f`等价于`f(x)`。2014年useR会议介绍magrittr之后,有人评价:
[url=http://www.r-statistics.com/2014/08/simpler-r-coding-with-pipes-the-present-and-future
-of-the-magrittr-package]the pipe operator is one (if not THE) most important innovation introduced,
this year, to the R ecosystem[/url]

Basics

Produce values

通过使用管道操作符,可以从语义上改变我们写代码的方式,使代码更加简洁易读,管道操作
符的功能为


          
  • 默认情况下,左边的结果默认作为右边函数的第一个参数,可省略,如下面的`transform`
            `as.Data`和`format`.
  • `%>%`可以以嵌套的方式使用,例如它可以作用于表达式来计算函数的参数,如
        `Date = paste(1973, Month, Day, sep = "-") %>% as.Date`
  • 如果不是传递作为第一个参数用`.`表示,如`aggregate(. ~ Date %>% format("%W"), ., mean)`
  • 公式中的`.`并不影响管道操作符,如`aggregate(. ~ Date %>% format("%W"), ., mean)`
  • 如果传递的右边函数只需要一个参数,那么可以省略参数和括号,`head`,当然`head(.)`和`head()`也可以
  • 管道操作符左边的函数(包含从上一步传递过来的`.`)为一元函数如`aggregate(. ~ Date %>% format("%W"), ., mean)`



  1. library(magrittr)
  2.     weekly <-
  3.       airquality %>%
  4.       transform(Date = paste(1973, Month, Day, sep = "-") %>% as.Date)
  5.       %>% aggregate(. ~ Date %>% format("%W"), ., mean) %>%
  6.       head
复制代码


上面代码包括三个部分,输入(airquality),一系列的数据转换(`transform`,
`aggregate`)和输出(weekly),类似函数的定义,所以它可以看成是一个函数的
定义和调用的过程,容易读写和理解。

当然你也可以不用`%>%`

  1.     weekly <- aggregate(. ~ format(Date,"%W"),
  2.       transform(airquality, Date = as.Date(paste(1973, Month,
  3.         Day, sep = "-"))),
  4.       mean)  
复制代码


显然这种写法可读性较差,难于理解,含有多对圆括号,更不利于别人的阅读;或者使用
中间变量来避免圆括号的使用,也不如利用管道操作符容易理解。此外,如果想在代码中间
添加新的计算,使用管道操作显然特别方便。

Produce functions

此外,利用`%>%`也可以构造简单的函数,与其基本用法其实是一样的(仅仅是基本用法定义函数的时候
即时调用返回结果),在构造函数的时候没有输入变量,用`.`替代输入变量即成功构造了一个函数

  1.     mae <- . %>% abs %>% mean(na.rm = TRUE)
  2.     mae(rnorm(10))

  3.     ## [1] 0.949347

  4.     ##等价于
  5.     mae <- function(x) {
  6.       mean(abs(x), na.rm = TRUE)
  7.     }
复制代码


匿名函数和lambda表达式

  1.    # 标准的函数定义
  2.     mtcars %>%
  3.     (function(x) {
  4.       if (nrow(x) > 2)
  5.         rbind(head(x, 1), tail(x, 1))
  6.       else x
  7.     })

  8.     ##             mpg cyl disp  hp drat   wt  qsec vs am gear carb
  9.     ## Mazda RX4  21.0   6  160 110 3.90 2.62 16.46  0  1    4    4
  10.     ## Volvo 142E 21.4   4  121 109 4.11 2.78 18.60  1  1    4    2

  11.     # lambda表达式,一元函数的参数用`.`表示

  12.     mtcars %>%
  13.     {
  14.       if (nrow(.) > 0)
  15.         rbind(head(., 1), tail(., 1))
  16.       else .
  17.     }

  18.     ##             mpg cyl disp  hp drat   wt  qsec vs am gear carb
  19.     ## Mazda RX4  21.0   6  160 110 3.90 2.62 16.46  0  1    4    4
  20.     ## Volvo 142E 21.4   4  121 109 4.11 2.78 18.60  1  1    4    2
复制代码


右边的匿名函数用括号包装起来,括号在管道操作符产生作用前优先计算右边括起来的表达式或者函数,
这时候默认情况下第一个参数应该为省略的`.`就不起作用了。

  1.     1:5 %>%
  2.       {paste(letters[.])}

  3.     ## [1] "a" "b" "c" "d" "e"
复制代码


此外匿名函数最有用的就是可以用于`*pply`系列函数

  1.    list(1,2,3) %>%
  2.       sapply(. %>% length)

  3.     ## [1] 1 1 1
复制代码


嵌套的函数调用

`.`在管道操作符的右边可以嵌套调用

  1.   1:5 %>%
  2.       paste(letters[.])

  3.     ## [1] "1 a" "2 b" "3 c" "4 d" "5 e"

  4.     # 等价于
  5.     1:5 %>%
  6.       paste(.,letters[.])

  7.     ## [1] "1 a" "2 b" "3 c" "4 d" "5 e"
复制代码


Advances

magrittr提供了三个其他的,辅助的管道操作符,在某些特定情况下,它们使我们更加
方便的实现各种操作

1. `%T>%`和`%>%`类似,只是它返回管道操作符左侧的值,通常用于流程中产生其他
    副作用的步骤(临时的,不改变左侧的结果继续传递给下一个步骤),如(print,
    plot, logging, etc)


  1.    rnorm(200) %>%
  2.     matrix(ncol = 2) %T>%
  3.     plot %>% # plot usually does not return anything.
  4.     colSums

  5.     ## [1] -9.25270 -7.98688

  6.     ## 其实是下面代码的简写形式
  7.     rnorm(200) %>%
  8.     matrix(ncol = 2) %>%
  9.     {plot(.);.} %>% # plot usually does not return anything.
  10.     colSums

  11.     ## [1] 11.197969  7.683612
复制代码


2.  `%$%`使左侧数据中变量的名称加载到流程的环境中方便我们直接提取,显然他等价于
    函数`with`

  1.     mtcars %$%
  2.       plot(mpg, wt)
复制代码


3.   `%<>% 必须是流程中的第一个管道操作符,最后的计算结果赋值给其左边变量,它主要作用是 把形如`foo
    \<- foo %\>% bar %\>% baz`的计算流程简化为`foo %\<\>% bar %\>% baz\`

此外为了使R中的基本操作符与管道操作更友好的结合起来,为这些操作符提供了别名:
    extract  `[`
    extract2    `[[`
    use_series  `$`
    add `+`
    subtract    `-`
    multiply_by `*`
    raise_to_power  `^`
    multiply_by_matrix  `%*%`
    divide_by   `/`
    divide_by_int   `%/%`
    mod `%%`
    and `&`
    or  `|`
    equals  `==`
    is_greater_than `>`
    is_weakly_greater_than  `>=`
    is_less_than    `<`
    is_weakly_less_than `<=`
    not `!`
    set_colnames    `colnames<-`
    set_rownames    `rownames<-`
    set_names   `names<-`
  1.     rnorm(100) %>% `*`(5) %>% `+`(5) %>%
  2.     {
  3.       cat("Mean:", mean(.), "Variance:", var(.),  "\n")
  4.       head(.)
  5.     }

  6.     ## Mean: 4.785676 Variance: 23.8642

  7.     ## [1]  7.806526 -4.416972 -1.273823  2.976003  7.568857 12.097451

  8.     # 可以写为
  9.     rnorm(1000)    %>%
  10.     multiply_by(5) %>%
  11.     add(5)         %>%
  12.     {
  13.        cat("Mean:", mean(.),
  14.            "Variance:", var(.), "\n")
  15.        head(.)
  16.     }

  17.     ## Mean: 4.982161 Variance: 26.18578

  18.     ## [1]  0.06189078  8.67467189  6.37717763  6.09563550 -0.65720166  4.04583594
复制代码


Ref

1. magrittr: Simplifying R code with pipes

2.  magrittr 1.5

3. magrittr vignette


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Simplifying Innovation Statistics Aggregate transform innovation important linux 表达式 管道

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-5 17:43