使用管道%>%获取system.time或复制工作

age*_*nis 4 r piping dplyr magrittr

我倾向于使用管道操作员(%>%,来自magrittrdplyr库).直到有一天,我试图system.time在右侧使用该命令.

system.time(mean(rnorm(1E7))) # ok
#### user     system      elapsed 
#### 3.52        0.05        3.58 
rnorm(1E7) %>% mean %>% system.time # ?
#### user     system      elapsed 
#### 0        0        0
Run Code Online (Sandbox Code Playgroud)

所以我去阅读文档并尝试了这个(它说你可以通过将它括在括号中来强制评估RHS,但它给出了相同的行为:

rnorm(1E7) %>% mean %>% (function(x) system.time(x))
#### user     system      elapsed 
#### 0        0        0
Run Code Online (Sandbox Code Playgroud)

我的问题如下:

1.system.time当放置在管道末端时,为什么命令不能按预期工作?

2.有没有办法测量由管道组成的一行代码的计算时间,而不必将整行放在括号内(这会消除管道的实际好处......)或使用proc.time?

注意:该replicate命令的问题相同.

Spa*_*man 14

我能做的第二件事就是创建一个包装器,system.time它接受一个未经评估的表达式并对其进行评估,然后你必须将大小写的表达式包装在大括号中并在管道时引用它,以便在我的包装器函数得到之前不会对它进行求值它的爪子:

> psystime = function(e){system.time(eval(e))}
> quote({rnorm(1e7) %>%  mean}) %>% psystime
   user  system elapsed 
  0.764   0.004   0.767 
> 
Run Code Online (Sandbox Code Playgroud)

我说第二好,因为最好的答案根本就是不要这样做.有时管道是问题,而不是解决方案.

另一种可能性是将您的管道表达式用引号括起来并将其提供给一个system.time包装器,该包装器将其参数的计算版本作为文本运行:

> esystime = function(e){system.time(eval(parse(text=e)))}
> "rnorm(1e7) %>%  mean" %>% esystime
   user  system elapsed 
  1.075   0.033   1.137 
Run Code Online (Sandbox Code Playgroud)

我猜这个用例实际上就是你有一个很长的管道,想要快速查看运行需要多长时间,所以你自然只想%>% system.time在最后敲打.它可能同样简单,假设您知道"行首"和"行尾"的键盘快捷键,可以system.time(在开始和)结束时使用.

  • `时运::运气(106)` (5认同)
  • 除了*system.time之外,还总是可以选择使用管道.即`system.time(rnorm(1E7)%>%mean)` (3认同)