将变量临时存储在一系列dplyr

时间:2019-05-09 17:32:43

标签: r dplyr

是否有一种方法可以暂停一系列管道以存储一个临时变量,以便以后在管道序列中使用该变量?

我找到了这个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))

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

2 个答案:

答案 0 :(得分:2)

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

df['days_active'] = df['days_active'].dt.days

请注意,这里我们也必须将df %>% { n = nrow(.) gather(., var, value, -Grp) %>% mutate(newval = value * n) } 传递到.,并且管道在块内继续。但是您可以随后放置其他部分

gather

答案 1 :(得分:1)

这是%>>%中的pipeR(管道运算符)的一个选项

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