2019独角兽企业重金招聘Python工程师标准>>>
1、赋值符号的陷阱
参考资料:
http://bbs.pinggu.org/thread-1247151-1-1.html
http://yihui.name/cn/2012/09/equal-and-arrow/
在R中,“=”表示传值,“<-”表示赋值,“=”在大多数情况下可以代替“<-”,但由于二者之间的细微差别,会导致一些错误。
1.1 关系比较时的陷阱
x=5;x>3; #返回TRUE
x<3; #返回FALSE
x<-3; #注意这里是将-3赋值给x,而不是比较x与-3的大小
所以为避免意外发生,应该养成操作符两边加空格的好习惯,否则后果可能会很严重。
1.2 传递参数的误导1
x=0;
mean(x=1:10); #输出5.5,x在这里是一个参数,用完即丢弃
x; #输出0,由于上面的x用完即丢弃,所以不改变原环境里x的值
mean(x <- 1:10); #输出5.5,在这里是改变原环境的x值,然后将x的值作为mean的参数
x; #输出1:10,因为上面改变了原环境的x值
个人看法:函数的参数还是不要随意扩大作用域为好
1.3 传递参数的误导2
matrix(1:6,ncol=2); #输出3×2的矩阵
matrix(1:6,ncol <- 2); #输出2×3的矩阵。在这里ncol不是matrix的默认参数,而是将“ncol <- 2”作为一个表达式。这个表达式首先在上级环境里建立了一个名为ncol的变量,赋值为2,然后将ncol的值,即表达式的结果,作为matrix的第一个参数,相当于matrix(1:6,nrow=2)
ncol; #输出2,该变量在由于前面使用了“<-”而生成
1.4 传递参数的误导3
> system.time(x <- runif(100))
用户 系统 流逝
0 0 0
> system.time(x = runif(100))
错误于system.time(x = runif(1000)) : 参数没有用(x = runif(1000))
#这个错误在于“=”是传值符号,因此该命令将x当作system.time的一个参数,并将runif(100)传递给x
#但是system.time函数本身并没有这样一个参数,因此出错
#根据这个原理可以在rnorm中再现同样类型的错误,如下:
> rnorm(x=3)
Error in rnorm(x = 3) : unused argument (x = 3)
2、因子和字符放在一起的意外
因子变量存储的是标签和数字,因此和字符放在一起发生类型强制转换时,会出现意外
x=gl(3,2,length=6,label=c('a','b','c'));
c(x,'d'); #输出"1" "1" "2" "2" "3" "3" "d"
c(as.character(x),'d') #输出"a" "a" "b" "b" "c" "c" "d"
3、NULL不能看作0
x=NULL; x=x+1; x; #输出numeric(0)
修正:将x明确赋值为0即可
x=0; x=x+1; x; #输出0
4、列表元素扩充时最好先初始化为一个空列表
x=list(); for (i in 1:2) {for (j in 1:2) {x[[i]][[j]]=1:5}}
#输出:错误于`*tmp*`[[i]] : 下标出界
修正1:将数字转成字符,或直接使用字符即可
x=list(); for (i in 1:2) {for (j in 1:2) {
x[[as.character(i)]][[as.character(j)]]=1:5}}
修正2:将下级元素先初始化为空列表
x=list(); for (i in 1:2) {for (j in 1:2) {
x[[i]]=list(); x[[i]][[j]]=1:5}}
修正3:直接建立给定长度的空列表,然后可以赋变量名
x=vector('list',length=5);
names(x)=1:5;
5、单行矩阵转为数据框的意外
x=matrix(1:5,1); #一行五列的矩阵
as.data.frame(x); #五个变量,每个变量只包含一个数据
as.data.frame(x[,1:5]); #一个变量,包含五个数据
6、parApply没有找到函数
这个出错原因可能是函数环境的问题,参考:
http://stackoverflow.com/questions/25728178/r-cluster-export-error-object-not-found
修正方法:使用clusterExport将找不到的函数加进来。
7、ifelse条件不够的问题
ifelse(3 > 2,1:3,4:6) #只返回1
原因:条件长度为1,所以只返回数据中的第一个元素
修正1:
ifelse(3 > 2,list(1:3),list(4:6))[[1]]
修正2:当条件真假对应的数据长度一致,且已知时
ifelse(rep(3 > 2,3),1:3,4:6)
8、四舍五入的0.5问题
rbind(seq(0, 4, by = .5), round(seq(0, 4, by = .5))) #并不是常见的四舍五入
原因:R默认的IEEE四舍五入方法,在涉及到0.5时,是向最近的偶数取整
修正:
rbind(seq(0, 4, by = .5), trunc(seq(0, 4, by = .5)+0.5))
9、向量内积、叉积、外积
在R语言中,cross product指的是内积(又称点积,dot product),即两等长向量的各元素对应相乘再求和,经常用于计算一个向量的平方和。可以使用函数crossprod(),也可以使用运算符“%*%”。该算法对于两个矩阵而言,即为矩阵乘法。
叉积(cross product)是矩阵中的名词,在统计学中使用不多,因此R中没有自带该算法的函数。
外积(outer product)和叉积不同,在R语言中指的是一个向量的每个元素和另一向量的每个元素相乘,结果为一个矩阵。可以使用运算符“%o%”或函数outer()进行运算。但函数outer()可修改对应元素之间的运算方式。