m*****n 发帖数: 3575 | 1 【 以下文字转载自 Programming 讨论区 】
发信人: minquan (三民主义), 信区: Programming
标 题: 从apply句型的潜在危险看R语言的俚语风格
关键字: R Python
发信站: BBS 未名空间站 (Sun Nov 12 01:34:56 2017, 美东)
apply句型是R最失败的句型,它的失败集中体现了R语言的底层结构的粗笨和任性
刚开始学R的同学可能都会被apply的所谓高效所惊叹
然而apply在R的本质就是元素枚举,它只是比列标枚举省了一步
sapply(1:10, print)
基本等同于以下的元素枚举
for( each in 1:10) print(each)
apply在应用时有两大缺陷,都与多变量函数有关
例如我要算一组数据,给定长宽,求长方形面积
或者对以长=20,宽=10的附近以0.1为精度的9*9偏扰动分析
但是apply家族的函数并没有提供同时变动多个自变量的计算,对不起,还是老实用for吧
那么我只变动一组数据,其余不变,可以算么?
这个用上匿名函数,还过得去
如果你有f(x1,x2,x3),只想变动x2,x1=a,x3=c
用
sapply( , function(x) f(a,x,c) )
如果说缺陷仅仅可以用R语言在编制时的功能简约来作借口,那么危险就是R语言的无可
推卸的责任了。
例如时间计算的常用包lubridate
require(lubridate)
dminutes(1:10)
会得到1到10分钟的时间长度
如果用这个作自变量做时间运算
在apply和元素枚举中都会出现意外
for( each in dminutes(1:10) ) print(each)
哈哈
得到的是 60 120 等等自然数
for( each in dminutes(1:10) ) print(class(each))
证实了在元素枚举中,R自行强迫把lubridate包定义的Duration类给转成数值类了
也就是说,仅仅做了个枚举,R就已经不经过你同意,把原来的类给降级成基础类了
apply不可避免的也会发生相同的错误
sapply(dminutes(1:10),function(x)x+Sys.time())
只有最土的下标枚举能避免
for( i in 1:10) print(dminutes(1:10)[i])
这在编程中是个危险,容易引发意想不到的错误
结论是apply基本不敢用
这就是R的俚语特性——
给了你一个榨汁器,可以榨柠檬,你以为拿来苹果、梨、香蕉都可以榨
但是对不起,那些都榨不了,会出错
甚至榨橙子都会出错
这就像英语,学了一个dogs,就以为mans可以用了,其实不行
英语是一种经验性的俚语,所谓的案例法,一个管用不代表类似的都管用
R真是深得英语的精髓
而python的只需list comprehension一个语法就把上述所有问题全部搞定
Python思维方式是大陆法,类似于汉语,学了一点,可以推及到任何相似的
羊肉,猪肉,鱼肉,虾肉,牛肉......
难怪Python在大数据领域被推为至尊,真是实至名归。 |
|