【问题标题】:Temporarily store variable in series of pipes dplyr临时存储一系列管道中的变量 dplyr
【发布时间】:2019-05-09 17:32:42
【问题描述】:

有没有办法暂停一系列管道来存储一个临时变量,以便以后在管道序列中使用?

我找到了这个question,但我不确定它是否与我正在寻找的一样。

这是一个示例数据框:

library(dplyr)
set.seed(123)
df <- tibble(Grp = c("Apple","Boy","Cat","Dog","Edgar","Apple","Boy","Cat","Dog","Edgar"),
             a = sample(0:9, 10, replace = T),
             b = sample(0:9, 10, replace = T),
             c = sample(0:9, 10, replace = T),
             d = sample(0:9, 10, replace = T),
             e = sample(0:9, 10, replace = T),
             f = sample(0:9, 10, replace = T),
             g = sample(0:9, 10, replace = T))

我要将df 转换为长格式,但在完成此操作后,我需要应用gather 之前的行数。

这就是我想要的输出的样子。在这种情况下,在管道开始之前存储行数如下所示:

n <- nrow(df)

df %>% 
  gather(var, value, -Grp) %>% 
  mutate(newval = value * n)
# A tibble: 70 x 4
   Grp   var   value newval
   <chr> <chr> <int>  <int>
 1 Apple a         2     20
 2 Boy   a         7     70
 3 Cat   a         4     40
 4 Dog   a         8     80
 5 Edgar a         9     90
 6 Apple a         0      0
 7 Boy   a         5     50
 8 Cat   a         8     80
 9 Dog   a         5     50
10 Edgar a         4     40
# ... with 60 more rows

在我的实际问题中,我有很长的管道链,如果我可以在管道结构中执行此操作会容易得多。我想做一些看起来像这样的事情:

df %>% 
  { "n = nrow(.)" } %>% # temporary variable is created here but df is passed on
  gather(var, value, -Grp) %>% 
  mutate(newval = value * n)

我可以做类似以下的事情,但看起来真的很草率。

df %>% 
  mutate(n = nrow(.)) %>% 
  gather(var, value, -Grp, -n) %>% 
  mutate(newval = value * mean(n))

有没有办法做到这一点,或者可能是一个好的解决方法?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您可以将代码块用于局部变量。这看起来像

    df %>% 
    { n = nrow(.)
      gather(., var, value, -Grp) %>% 
      mutate(newval = value * n)
    }
    

    注意我们必须在这里将. 传递给gather 并且管道在块内继续。但是你可以在后面放其他部分

    df %>% 
    { n = nrow(.)
      gather(., var, value, -Grp) %>% 
      mutate(newval = value * n)
    } %>% 
    select(newval)
    

    【讨论】:

    • 不错。出于好奇,我假设代码块可以嵌套。
    • 当然。代码块可以嵌套。您只需要注意当前作为 . 参数传递的内容。
    【解决方案2】:

    这是来自pipeR 的带有%&gt;&gt;%(管道运算符)的选项

    library(pipeR)
    library(dplyr)
    library(tidyr)
    df %>>% 
       (~ n  = nrow(.)) %>% 
        gather(., var, value, -Grp) %>%
        mutate(newval = value * n)
    # A tibble: 70 x 4
    #   Grp   var   value newval
    #   <chr> <chr> <int>  <int>
    # 1 Apple a         2     20
    # 2 Boy   a         7     70
    # 3 Cat   a         4     40
    # 4 Dog   a         8     80
    # 5 Edgar a         9     90
    # 6 Apple a         0      0
    # 7 Boy   a         5     50
    # 8 Cat   a         8     80
    # 9 Dog   a         5     50
    #10 Edgar a         4     40
    # … with 60 more rows
    

    【讨论】:

    • 你能解释一下第二行的内容吗?我刚刚查找了pipeR 管道并立即了解了基础知识,但我不明白为什么会这样。 dfpipeR 用管道传送到括号中,所以管道仅将df 发送到.,但在那之后我迷路了。
    • @hmhensen %&gt;% 语法中的. 是从%&gt;%lhs 输出的数据,用于在管道的右轴上进行处理。 ~ 是匿名函数调用(您可以在 tidyverse 中找到类似的语法)以生成对象标识符(n)将其存储在环境中以供以后处理。而gather 步骤再次使用来自df. 数据,即数据本身,然后变异只是 dplyr 语法来创建一个新列
    • 我仍然不确定为什么 pipeR 管道在这里工作,而 magrittr 管道却没有。 df 是如何进入第二个管道的?为什么n 没有通过? MrFlick 对括号的使用对我来说很有意义。不过,我没有在这里关注那部分,因为括号中只发生了一件事。我想我缺乏编程经验。
    • 如果您检查最后一步,@hmhensen n 可用。
    • 对不起,我的意思是为什么括号外的对象包括dfn?我明白为什么n 是输出,但是df 如何获得输出?既然df 是由nrow 作用的,它又如何完整地从括号中出来?
    猜你喜欢
    • 1970-01-01
    • 2016-06-18
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    相关资源
    最近更新 更多