使用数据框时,通常需要一个子集.但是不鼓励使用子集函数.以下代码的问题是数据框名称重复两次.如果你复制并粘贴和munge代码,很容易不会意外地改变第二次提到的adf,这可能是一场灾难.
adf=data.frame(a=1:10,b=11:20)
print(adf[which(adf$a>5),]) ##alas, adf mentioned twice
print(with(adf,adf[{a>5},])) ##alas, adf mentioned twice
print(subset(adf,a>5)) ##alas, not supposed to use subset
Run Code Online (Sandbox Code Playgroud)
有没有办法在不提及adf两次的情况下编写上述内容?不幸的是,使用with()或within(),我似乎无法访问整个adf?
子集(...)函数可以很容易,但他们警告不要使用它:
这是一种便于交互使用的便利功能.对于编程,最好使用像[的标准子集函数,特别是参数子集的非标准评估可能会产生意想不到的后果.
经过一番思考,我写了一个超级简单的函数,名为给定:
given=function(.,...) { with(.,...) }
Run Code Online (Sandbox Code Playgroud)
这样,我就不必重复 data.frame 的名称。我还发现它比filter(). 见下文:
adf=data.frame(a=1:10,b=11:20)
given=function(.,...) { with(.,...) }
with(adf,adf[a>5 & b<18,]) ##adf mentioned twice :(
given(adf,.[a>5 & b<18,]) ##adf mentioned once :)
dplyr::filter(adf,a>5,b<18) ##adf mentioned once...
microbenchmark(with(adf,adf[a>5 & b<18,]),times=1000)
microbenchmark(given(adf,.[a>5 & b<18,]),times=1000)
microbenchmark(dplyr::filter(adf,a>5,b<18),times=1000)
Run Code Online (Sandbox Code Playgroud)
使用微基准
> adf=data.frame(a=1:10,b=11:20)
> given=function(.,...) { with(.,...) }
> with(adf,adf[a>5 & b<18,]) ##adf mentioned twice :(
a b
6 6 16
7 7 17
> given(adf,.[a>5 & b<18,]) ##adf mentioned once :)
a b
6 6 16
7 7 17
> dplyr::filter(adf,a>5,b<18) ##adf mentioned once...
a b
1 6 16
2 7 17
> microbenchmark(with(adf,adf[a>5 & b<18,]),times=1000)
Unit: microseconds
expr min lq mean median uq max neval
with(adf, adf[a > 5 & b < 18, ]) 47.897 60.441 67.59776 67.284 70.705 361.507 1000
> microbenchmark(given(adf,.[a>5 & b<18,]),times=1000)
Unit: microseconds
expr min lq mean median uq max neval
given(adf, .[a > 5 & b < 18, ]) 48.277 50.558 54.26993 51.698 56.64 272.556 1000
> microbenchmark(dplyr::filter(adf,a>5,b<18),times=1000)
Unit: microseconds
expr min lq mean median uq max neval
dplyr::filter(adf, a > 5, b < 18) 524.965 581.2245 748.1818 674.7375 889.7025 7341.521 1000
Run Code Online (Sandbox Code Playgroud)
我注意到given() 实际上比 快一点with(),因为变量名的长度。
,的巧妙之处在于given,您可以在不进行赋值的情况下内联执行一些操作:给定(data.frame(a=1:10,b=11:20),.[a>5 & b<18,])
| 归档时间: |
|
| 查看次数: |
376 次 |
| 最近记录: |