使用点(“.”)、波浪线(“~”)和管道(“%>%”)运算符的R组合。

11

我一直在寻找答案,但仍然无法完全理解它们。例如,其中最清晰的一个 (这里),还有其他一些 (1,2,3) 提供了关于点的各种用法的具体示例,但我无法理解,例如,在此处的应用:

car_data <- 
  mtcars %>%
  subset(hp > 100) %>%
  aggregate(. ~ cyl, data = ., FUN = . %>% mean %>% round(2)) %>%
  transform(kpl = mpg %>% multiply_by(0.4251)) %>%
  print

#result:
  cyl   mpg  disp    hp drat   wt  qsec   vs   am gear carb    kpl
1   4 25.90 108.0 111.0 3.94 2.15 17.75 1.00 1.00 4.50 2.00 11.010
2   6 19.74 183.3 122.3 3.59 3.12 17.98 0.57 0.43 3.86 3.43  8.391
3   8 15.10 353.1 209.2 3.23 4.00 16.77 0.00 0.14 3.29 3.50  6.419

以上代码摘自magrittr中%>%的解释,我试图理解管道运算符(我知道它会给出先前计算的结果,但当aggregate代码行混合了.%>% 时,我就很迷惑了)。

所以,我无法理解上面的代码。我有结果(我将其放在上面)。但我不明白它是如何达到这个结果的,特别是在aggregate代码行中,它使用了点和~符号。我知道~表示“其他所有变量”,但点号代表什么?它还有其他含义或应用吗?在特定函数内部使用管道操作符代表什么?


我认为这里令人困惑的是aggregate调用中公式中.的不同用法以及其在magrittr包中使用方式。根据 ?formula:“公式中 . 有两种特殊解释。通常的解释是在模型拟合函数的数据参数上下文中,表示‘除了公式中其他未列出的所有列’:参见terms.formula。只在update.formula的上下文中,它才意味着‘此前在公式的这个部分中的内容’。” - zack
3个回答

19

这条代码使用了三种不同的方式来使用.

         [1]             [2]      [3]
aggregate(. ~ cyl, data = ., FUN = . %>% mean %>% round(2))

一般来说,您将管道中的值传递到函数中的特定位置,使用.,但也有一些例外情况。一个例外是当.在公式中时。在R中,~用于创建公式。管道不会改变公式的含义,因此它的行为就像没有任何转义符一样。例如:

aggregate(. ~ cyl, data=mydata)

这只是因为aggregate需要一个同时具有左右两个方面的公式。所以在[1]处的.表示“数据集中的所有其他列”。这种用法与magrittr没有任何关系。

[2]处的.是作为管道传递的值。如果将纯粹的.作为函数的参数,那么该值将被放置在那里。因此,subset()的结果将进入data=参数。

magrittr库还允许您使用.变量定义匿名函数。如果链以.开头,则视为函数。

. %>% mean %>% round(2)

等同于

function(x) round(mean(x), 2)

所以您只需在[3]处使用.创建自定义函数即可。


4

在聚合语句中,"Dot" 有三种用法:

  • aggregate.formula the formula method of aggregate specifies a formula in which the left hand side (LHS) of the ~ defines the variables to apply the function to and the right hand side of the ~ defines the variables to group by. It uses dot in the formula to mean all other variables not already mentioned in the formula. For example, using the builtin ToothGrowth data frame having columns len, supp and dose these are the same. We group by supp whereas mean acts on each of len and dose.

    aggregate(. ~ supp, ToothGrowth, mean)
    aggregate(cbind(len, dose) ~ supp, ToothGrowth, mean)
    
  • RHS of pipe when used on the right hand side (RHS) of a pipe magrittr uses dot to represent the input, i.e. whatever is on the left hand side of the pipe. Thus, these are the same:

    4 %>% sqrt(.) # use of dot on RHS
    sqrt(4)
    
  • LHS of pipe when used on the left hand side of a pipe magrittr uses dot to represent a function definition. For example, these two function defintions both define a function that squares its argument:

    square1 <- . %>% .^2 # use of dot on LHS
    square2 <- function(x) x^2
    

也许最容易理解的方法是将问题中的例子写成没有点的形式:

mtcars0 <-  mtcars %>%
  subset(hp > 100)

aggregate(
  cbind(mpg,disp,hp,drat,wt,qsec,vs,am,gear,carb) ~ cyl,  # cbind(...) in place of .
  data = mtcars0, # mtcars0 in place of .
  FUN = function(x) round(mean(x), 2)) # instead of . %>% etc.

0

由于有多个函数按顺序执行,一个选项是使用 compose

library(tidyverse)
f1 <- list(mean,  partial(round, digits = 2))
mtcars %>% 
    filter(hp > 100) %>% 
    group_by(cyl) %>% 
    summarise_all(list(~lift(compose)(f1)(.))) %>% 
    mutate(kpl = mpg * 0.4251) #multiply_by is a bit verbose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接