在每个过滤步骤打印数据框尺寸

时间:2018-01-09 11:19:26

标签: r tidyverse magrittr

我正在使用tidyverse来过滤掉一个数据帧,并希望在中间对象的尺寸(或nrows)的每一步打印。 我以为我可以简单地使用magrittr的三通管道操作员,但它不起作用。 我想我理解发球管背后的概念,但无法弄清楚出了什么问题。我进行了广泛的搜索,但没有找到太多关于T形管的资源。

我用mtcars数据集构建了一个简单的例子。如果我用dim()或nrow()替换,打印中间对象可以正常工作。

library(tidyverse)
library(magrittr)

mtcars %>% 
    filter(cyl > 4) %T>% dim() %>%
    filter(am == 0) %T>% dim() %>%
    filter(disp >= 200) %>% dim()

我当然可以在R base中写这个,但是我想坚持tidyverse精神。我可能会对tee pipe概念有所了解,任何意见/解决方案都将受到高度赞赏。

修改 在@hrbrmstr和@akrun很好和快速的答案后,我再次尝试坚持tee管道操作员而不编写函数。我不知道为什么我之前没有找到答案,但这里是我正在寻找的语法:

mtcars %>% filter(cyl > 4) %T>% {print(dim(.))} %>% filter(am == 0) %T>% {print(dim(.))} %>% filter(disp >= 200) %>% {print(dim(.))}

尽管需要一个功能,@ hrbrmstr解决方案确实更容易“清理”。

4 个答案:

答案 0 :(得分:5)

@ akrun的想法有效,但它不是惯用的tidyverse。 tidyverse中的其他功能(如print()glimpse())会无形地返回数据参数,因此无需诉诸{}即可对其进行管道传输。那些{}使您在完成了正在进行的工作后很难清理管道。

尝试:

library(tidyverse)

tidydim <- function(x) {
  print(dim(x))
  invisible(x)
}

mtcars %>%
  filter(cyl > 4) %>%
  tidydim() %>% 
  filter(., am == 0) %>%
  tidydim() %>% 
  filter(., disp >= 200) %>%
  tidydim()

这样你的&#34;清理&#34; (即不生成临时控制台输出)可以快速/轻松地删除tidydim()从函数中删除print(…)

答案 1 :(得分:3)

%T>%中的管magrittr是为这种情况创建的:

library(magrittr)
library(dplyr)
mtcars %>%
  filter(cyl > 4)     %T>% {print(dim(.))} %>%
  filter(am == 0)     %T>% {print(dim(.))} %>%
  filter(disp >= 200) %T>% {print(dim(.))}

如果您像我一样认真,可以使用Rstudioalt + selection中轻松阅读和修改。

如果你不喜欢括号,你也可以在这里使用@hrbrmstr的功能,除非你不需要最后一行。

几个月后重新审视这里的想法概括了@ hrbmst的解决方案,这样你就可以打印出你想要的东西并返回输入来继续管道。

library(tidyverse)
pprint <- function(.data,.fun,...){
  .fun <- purrr::as_mapper(.fun)
  print(.fun(.data,...))
  invisible(.data)
}

iris %>%
  pprint(~"hello")           %>%
  head(2)                    %>%
  select(-Species)           %>%
  pprint(rowSums,na.rm=TRUE) %>%
  pprint(~rename_all(.[1:2],toupper)) %>%
  pprint(dim)

# [1] "hello"
#    1    2 
# 10.2  9.5 
#   SEPAL.LENGTH SEPAL.WIDTH
# 1          5.1         3.5
# 2          4.9         3.0
# [1] 2 4

答案 2 :(得分:2)

我们可以使用print

中的{}
mtcars %>%
   filter(cyl > 4) %>%
   {print(dim(.))
    filter(., am == 0) } %>%
   {print(dim(.))
    filter(., disp >= 200)} %>%
   {print(dim(.))
   .}
#[1] 21 11
#[1] 16 11
#[1] 14 11
#    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#1  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#2  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#3  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#4  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
#5  16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
#6  17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
#7  15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
#8  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
#9  10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
#10 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
#11 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
#12 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
#13 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
#14 19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2

答案 3 :(得分:2)

使用软件包mmpipe,您可以为作业定义一个自定义管道,并具有非常紧凑的代码

library(tidyverse)
library(magrittr)
# devtools::install_github("moodymudskipper/mmpipe")
library(mmpipe)

add_pipe(`%dim>%`,substitute({. <- b; print(dim(.)); cat("\n"); .}, list(b = body)))

mtcars %dim>% 
  filter(cyl > 4) %dim>%
  filter(am == 0) %dim>%
  filter(disp >= 200)
# [1] 21 11
# 
# [1] 16 11
# 
# [1] 14 11
#
#     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
# 1  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
# 2  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
# ...