继续深入学习R语言,争取对其比较熟悉
函数
#R语言编程的核心就是函数
#count the number of odd integers in x
oddcount <- function(x){
k <- 0
for(n in x){
if(n%%2==1) k <- k + 1
}
print(paste("the odd number is:",k,sep = ""))
return(k)
}
x <- c(1,2,4,2,5)
oddcount(x)
#R语言尽可能避免使用循环,如果要写,也要简洁
#慎重使用没有显示调用的return()
#使用超赋值运算符 <<- 在函数内部给全局变量赋值```
#矩阵
也可以称作是向量,矩阵还有两个附加的属性,行数和列数
m <- rbind(c(1,2),c(3,4))
使用rbind将两个向量结合成一个矩阵
矩阵乘法运算,%*%
m%*%m
从矩阵中提取出子矩阵
m[1,]
m[,2]```
list列表
#其中内容的各项可以属于不同的数据类型
x <- list(u=c(2,3),v="abc")
x$u
x$v
#x[1]表示获取第一个组件,x[[1]]表示获取第一个组件里面的值(向量)
#但是x[[2]]表示获取第二个组件里面的值
x[[1]]
#要获取具体的值,这样操作
x[[1]][2]
#列表的一种常见用法是把多个值打包组合到一起,然后从函数返回
hn <- hist(Nile)
hn
#另外一种比较简洁的打印方式
#str表示structure,这个函数可以显示任何R对象的内部结构
str(hn)```
#数据框
其实是列表,只不过列表中的每个组件是由前面提到的矩阵数据的一列构成的向量
所以data.frame构造函数传入的是列表,当然如果传单个向量也可以,不过就是没有名字吧
如果需要名字,那么就要指定向量的名字
d <- data.frame(list(kids=c("jack","kevin"),ages=c(21,22)))
d1 <- data.frame(numbers=c(1,2),desc=c("ac","ab"))
str(d)
d
通常数据框是通过读取文件或者数据框来创建的```
类
#S3类,实例仅仅是列表,但是有个属性:类名
#hist输出的还有一个属性,用来指定列表的类,即histogram类
#然后指定类是为了使用泛型函数,泛型函数代表一个函数族,每个函数有相似的功能,
#但是适用于某个特定的类,所以列表有这个属性,就可以作为区分,如plot()函数就是一个函数族```
#向量
循环补齐,筛选,向量化(对向量的每一个元素应用函数)
适用typeof()来查看数据类型
x <- c(1,2,3,4)
typeof(x)
要想添加或者删除元素,则重新给向量赋值
x <- c(x[1:2],5,x[3:4])
x
获取向量长度
length(x)
要使用向量中特定的元素,必须首先去声明,而不能直接y[1] <- 2这样,必须像下面这样
y <- vector(length=2)
y[1] <- 2
y[3] <- 4
y
或者这样
y <- c(2,4)
使用c()创建了一个新向量,然后绑定给变量y
函数式语言中,读写向量中的元素,由函数来完成,R如果并不知道y是一个向量
那么函数就没有执行的对象```
循环补齐
c(1,2,3) + c(4,2,6,3)
x <- rbind(c(1,2),c(2,4))
x + c(1,2)```
#向量的运算
+也是函数,"+"(),使用双引号是因为+是特殊字符
2+3
"+"(2,3)
*函数使用方式是元素与元素相乘```
向量索引
#选择给定向量中特定索引的元素构成子向量
#向量1[向量2],返回向量1中索引为向量2的元素
y <- c(1,2,4,5,2)
y[c(1,4)]
#负数下表表示把相应的元素剔除
y[-2]
#去除最后一个元素
y[1:length(y)-1]
y[-length(y)]```
#使用:运算符创建向量
5:8
和python切片中冒号不一样的是,这里既包含前面也包含后面元素
另外冒号运算符优先级高于-号
1:5-1
1:(5-1)```
seq()函数创建向量,等差序列
seq(1,5,2)
#然后可以使用下面的功能
x <- c(5,23,41,42)
seq(x)
#就是seq()会建立一个x向量的等差索引,并且如果x为空的时候,会正确的计算空值NULL
for(i in seq(x)){
print(i)
print(x[i])
}```
#rep()函数可以将同一个常数放在长向量中
x <- rep(8,4)
将8重复4次,创建一个向量
x <- rep(c(1,2,3),3)
each参数,指定前面要重复的东西重复次数
x <- rep(c(1,2),each=2)
1 1 2 2```
使用all()和any()
#报告参数是否至少有一个或者全部为TRUE
x <- 1:10
all(x>8)
any(x>9)
#也就是首先形成一个布尔向量,然后进行判断
#筛选也是如此,形成布尔向量,然后只索引为TRUE的索引值```
#向量化
对向量x中的每一个元素使用函数f()
提高R代码执行速度的有效方法之一就是向量化,将应用到向量的函数实际应用在每一个元素上
一些向量化运算,+ * >
如果一个函数使用了向量化的运算符,那么它也被向量化了
一些函数,sort(),round()都是向量化的
f <- function(x,c){
return((x+c)^2)
}
传入的参数,c作为标量,x为向量就会产生循环补齐进行运算
当然也可以传入c为向量,如果要限制为标量,那么要进行判断
f <- function(x,c){
if(length(c)!=1){
stop("vector c not allowed")
}
return((x+c)^2)
}```
向量输入与输出
#有的函数直接返回向量
z12 <- function(z){
return(c(z,z^2))
}
x <- 1:8
z12(x)
matrix(z12(x),ncol=2)
#在sapply诸如此类的函数里,调用函数不需要带括号
#sapply会直接输出矩阵
sapply(x,z12)```
#NA表示缺失值,NULL表示不存在的值
x <- c(88,NA,12,168,13)
y <- c(x[-2],NULL)
mean(x)
mean(y)
mean(x,na.rm = T)
R会自动跳过空值NULL,但是不会跳过NA
NULL一个用法是在循环中创建向量,其中每次迭代在向量上增加一个元素
z <- NULL
for(i in 1:10){
z <- c(z,i)
}
NULL被作为不存在而计数,也就是相当于没有```
筛选
#R语言函数式特性的另外一个特征
z <- c(5,2,-3,1)
z[z*z > 4]
#首先获取一个布尔值向量,然后用得到的布尔值向量筛选出z中所需要的元素
z[z>3] <- 0```
#使用subset()进行筛选
它与普通方法区别在于处理NA值上
x <- c(6,1:3,NA,12)
x[x>5]
subset默认忽略NA
subset(x,x>5)```
which函数
#前面筛选都是获得筛选后的值,但是which函数将获取到满足条件的索引值
which(z*z>4)
#which报告在z*z>4运行后,哪些值是TRUE,返回其索引
#它有个用法非常方便就是在向量中找出满足一定条件元素首次出现的位置
first1a <- function(x){
return(which(x==1)[1])
}
x <- c(3,2,1,4,1,4,5)
print(first1a(x))```
#向量化的ifelse()函数
除了正常用法ifelse(b,u,v),b为真,返回u,否则返回v
向量化用法是b[i]为真,返回u[i],否则返回v[i],最终返回一个向量
x <- 1:10
ifelse(x>5,TRUE,FALSE)```
判断向量是否相等
#==不能使用,因为==是向量化的,比较的是向量中每个元素是否相等
x <- 1:3
y <- c(1,3,4)
x == y
#当然可以这样做
all(x == y)
#也可以简单的使用identical函数
identical(x,y)
#判断对象是否完全一样
z <- c(1,2,3)
#identical不一样的原因是c()产生的是浮点数,而1:3产生的是整数,但是==可以正常,因为毕竟值是一样的
identical(x,z)
all(x == z)```
#使用names()函数给向量命名
x <- c(1,2,3)
names(x) <- c("i","love","you")
使用names索引元素
x["i"]
移除名字
names(x) <- NULL```
c()
#传递到c()参数有不同类型,则会被降级到同一个类型,该类型最大程度的保留他们的共同特性
c(5,1,"iloveyou")
#全成字符串了
#另外c()对数据有扁平化效果,和Python不一样
c(1,2,4,c(2,4,4))```
网友评论