数据分析系列-R-数据

引言

上次做了R的介绍和安装点击这里直达,主要介绍了在各个不同的系统中怎么安装R软件,还基础的介绍了怎么使用R,今天探讨下R的数据相关的知识。

R的对象

R中的所有对象都建立在一组基本的内嵌对象之上的,对象的类决定了其在R中的存储方式,同时R的对象也都属于某个类,而R提供了一组面向对象编程的机制。这段话我也没懂!

R的基本对象类型

R有如下的基本对象类型:

  • 基本向量
  • 复合对象
  • 特殊对象
  • R语言(即R代码)
  • 函数
  • 内置对象
  • 字节码对象

以下简单介绍以下R的常用的对象。

向量

向量是R中最基本的对象,也是最常用的存储数据的对象。特别的,向量中的元素都会被转成同样的数据类型,也就是说向量的元素都是同种类的数据。R有多种创建向量的方法,其中最常见的是c函数:

> v <- c(1,2,3,4)
> v
[1] 1 2 3 4

另外,我们可以使用操作符:生成向量:

> 1:10
[1] 1 2 3 4 5 6 7 8 9 10

另外一个更加灵活的是seq函数方式:

> seq(from=1, to=10, by=2)
[1] 1 3 5 7 9

其中by参数理解为步长,表示生成从1到10步长为2的向量。seq还有其它很多种用法来生成序列,可以使用help('seq')来查看帮助文档。

逻辑向量

这里特别说明下逻辑向量,R是允许操作逻辑向量的。其中逻辑向量的元素可以被赋予的值有TRUE,FALSENA,我们可以试试下面的语句:

> v
[1] 1 2 3 4
> m <- v > 2.5
> m
[1] FALSE FALSE TRUE TRUE
> class(m)
[1] "logical"

其中v是第一个代码创建的向量。而m就是我们通过逻辑运算符$\lt、\leq、\gt、\geq$来判断生成的一个向量。

矩阵

矩阵也是R中常用的对象类型,矩阵可以看成多个带有下标类型的的元素集合,和数学中的矩阵类似,一般我们可以把其中某个元素表示为$a_{ij}$,更通用的可视化的矩阵如下:
$$
\begin{equation}
A_{i \times j} =
\begin{bmatrix}
a_{11} & a_{12} & a_{13} & \cdots & a_{16} \
a_{21} & a_{22} & a_{23} & \cdots & a_{26} \
\vdots & \vdots & \vdots & \ddots & \vdots \
a_{i1} & a_{i2} & a_{i3} & \cdots & a_{ij}
\end{bmatrix}
\end{equation}
$$

在R中生成矩阵的函数为matrix:

> m <- matrix(c(1:12),c(3,4))
> m
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12

可以看到我们用matrix函数将向量c(1:12)构建成了一个$3 \times 4$的矩阵,并且矩阵的填充是按照列填充的,如果我们想按照行填充命令如下:

> m <- matrix(c(1:12),c(3,4),byrow = TRUE)
> m
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12

我们这里会看到矩阵m的长度是等于$i \times j$的:

> t <- matrix(c(1:1500),c(30,50))
> length(t)
[1] 1500

所以创建矩阵时要注意矩阵的长度,否则会产生错误。

因子

因子为处理分类数据提供了一种非常有效的方法,因子是一个对等长的的其它向量进行分组的向量对象。R同时提供了有序和无序因子。我们先看一个例子:

> t <- c(1,2,5,2,5,2,4,3,1,2)
> factor(t)
[1] 1 2 5 2 5 2 4 3 1 2
Levels: 1 2 3 4 5

首先因子是一个向量,其次因子有个不同的参数就是Levels,这个实际上是向量t中所有的元素去重(unique)后的值,举一个因子的使用:

# 假设有若干省的人的提供样本体重数据
# state表示包含数据的省份
state <- c("上海", "山西", "浙江", "四川", "四川",
"广东", "湖南", "湖南", "浙江", "河南",
"四川", "河南", "浙江", "浙江", "山西",
"上海", "山西", "广东", "湖南", "河南",
"浙江", "四川", "四川", "湖南", "山西",
"江苏", "四川", "河南", "河南", "江苏")

# weight表示对应的省的样本体重数据不含小数
weight <- c(60, 49, 40, 61, 64,
60, 59, 54, 62, 69,
70, 42, 56, 61, 61,
61, 58, 51, 48, 65,
49, 49, 41, 48, 52,
46, 59, 46, 58, 43)

# 获取省份的样本的因子水平
fs <- factor(state)

# 计算每个省份样本的平均体重
average_weight <- tapply(weight, fs, mean)

计算的结果如下:

> average_weight
广东 河南 湖南 江苏 山西 上海 四川 浙江
55.50000 56.00000 52.25000 44.50000 55.00000 60.50000 57.33333 53.60000

列表

列表是一种泛化的向量(没错它又是向量的变种),但它和向量不同就是列表不要求元素都是同一类型,列表也是有序集合构成的对象,它包含的对象我们又可以成为分量:

Lst <- list(name="阿三", wife="查无此人", 
no.children=3, child.ages=c(4,7,9))

# 没搞懂老婆都查无此人了怎么还有孩子?手动大笑

其中,列表的分量是可以包含不同的模式或者类型,如一个列表可以包括数值向量、逻辑向量、矩阵、复向量、函数、······,简直是来者不拒。而且分量会被编号,所以可以通过编号来访问分量:

# 比如想访问阿三可以这样
> Lst[[1]]
[1] "阿三"

# 也可以这样
> Lst$name
[1] "阿三"

# 如果想知道阿三第二个孩子的年龄我们可以这样
> Lst[[4]][2]
[1] 7

# 还可以这样
> Lst$child.ages[2]
[1] 7

# 再来一个彩蛋:定义一个函数,输入阿三的第几个孩子返回一段话
f <- function(i) paste("我有个朋友叫",Lst$name,",他的老婆",Lst$wife,",但是他居然有",Lst$no.children,"个孩子,而且第",i,"个孩子",if (Lst$child.ages[i] >= 15) "不仅可以读书还可以喝酒了" else if(Lst$child.ages[i] < 15 && Lst$child.ages[i] >= 6) "正在苦逼的读书吧" else "或许能在幼儿园找个女朋友?"
,sep="")

# 运行结果
> f(1)
[1] "我有个朋友叫阿三,他的老婆查无此人,但是他居然有3个孩子,而且第1个孩子或许能在幼儿园找个女朋友?"
> f(2)
[1] "我有个朋友叫阿三,他的老婆查无此人,但是他居然有3个孩子,而且第2个孩子正在苦逼的读书吧"
> f(3)
[1] "我有个朋友叫阿三,他的老婆查无此人,但是他居然有3个孩子,而且第3个孩子不仅可以读书还可以喝酒了"

# 我到底在玩什么啊!!!!!

数据框

数据框也是R常用的数据对象,数据框是和矩阵类似的一种结构,在数据框中,不同的列是可以为不同的对象。一般可以使用data.frame函数来创建数据框对象:

# 我们沿用因子中的数据即省份的体重样本数据来构建数据框
> weight_by_state <- data.frame('省份'=state,'体重'=weight)

如果有符合数据框限制的列表可以直接使用as.data.frame()函数转换为数据框,从外部环境读取数据使用read.table()read.csv均可以创建数据框。

一般数据框有如下的限制条件:

  • 分量必须是向量(数值、字符、逻辑),因子,数值矩阵,列表或其它数据框
  • 矩阵,列表和数据框为新的数据框提供了尽可能多的变量,因为它们各自拥有列,元素或者变量
  • 数值向量,逻辑值,因子保持原有格式,而字符向量会被强制转换成因子
  • 在数据框中以变量形式出现的向量结构必须长度一致,矩阵结构必须有一样的行数

数组

最后一个介绍的是数组(其余的类型用的较少就不再介绍),数组是数组可以看作是带有多个下标类型相同的元素集合:

> z <- 1:1500
> dim(z) <- c(3,5,100)

通过对dim属性的赋值(赋值的是维度向量),这样就将向量z成为了一个$3 \times 5 \times 100$的数组。所以z的1500个元素,元素的下标可以从1一直标记到对应元素的值。

除了dim()函数创建数组,更通用的可以使用array()函数创建数组:

> s <- array(1:1500,c(3,5,100))
> class(s)
[1] "array"

对象的模式和属性

对象的模式mode是指是该对象基本要素的类型,这是专门用来描述一个对 象特征的术语。另外还有一个所有对象都有的特征是长度length,如果你想知道一个对象更详细的特征可以使用attributes函数来获取:

> attributes(s)
$dim
[1] 3 5 100

我们把模式和长度称为对象的内在属性。而且对象的模式和长度属性是可以改变的。

今天在坐火车,就写到这里吧,后面会有继续的内容。结束