原文链接 : r语言与数据分析实战1
搞清楚我们面对的数据类型是什么,并能实现数据类型之间的转换
需要认真学习以下函数:
mode()
: 用来查看数值类型的函数;
as.numeric()
: 将数据类型转换为数值型类型的函数;
as.logical()
: 将数据类型转换为逻辑型类型的函数;
as.cha\fracter()
: 将数据类型转换为字符型类型的函数。
在我们开始学习R
语言数据类型之前,先让我们根据例子来看看3
个简单的概念。
在R语言中,赋值符号有三种,分别如上图所示。大家可以根据自己的喜好选择使用~但是一般来说,大部分人都会选择中间的赋值方式,因为它更为形象。
现在我们正式开始学习R语言中的数据类型。
逻辑型数据的定义方式很简单,就是直接写上 TRUE
或 FALSE
的大写字母即可。
注意:R 只认大写的 TRUE
或 FALSE
。
它的运算规则有3种,如下图所示:
我们可以通过一个例子来加深对逻辑型数据
及运算规则的理解。
从上图的执行过程中,我们能看出x
实际上应该小于y
的,所以当我判断x
大于y
的时候,你能从右边的环境变量框
中看见,z
的值为FALSE
。
再检验一下,用mod()
函数来看看z现在的数据类型。WALA! 结果为logical
,逻辑型。
最后我们来一条一条执行逻辑型数据的运算规则,看起来很清晰明了吧~
数值型数据
就是我们数学中学过的实数啦,包含正数、0
和负数。也是我们最容易理解的数据类型了;
其中的“四则运算”,也是我们最熟悉的运算规则啦!我就不在这里多啰嗦了哟。
在R
中,我们把用' '
或者" "
包含起来的数据称为字符型数据
。
让我们来看看字符型数据
是什么样子的,以hello world
为例,嘿嘿。
恩,看来没错,mode()
函数告诉我们,x
和y
都是cha\fracter
字符型变量
R
语言数据类型的转换很“显式”,因为它是通过函数做到的,不会出现一不小心就被默认转换坑了的情况,不要问我是怎么知道的…
举个例子来看看逻辑型数据
转成数值型数据
是怎么做的吧。
那么问题来了,数值型数据
是否能转换为字符型数据
呢?哈哈,好奇害死猫,我不告诉你,快去自己试试吧。
#将 t 的数据类型转换为数值型,并输出 t 的值
t <- 'TRUE'
#----start----
mode(t)
t2 <- as.numeric(as.logical(t))
mode(t2)
t2
#-----end-----
我会介绍R都有哪些对象类型用来存储数据,也会顺便介绍一些常用的功能函数。然后,就轮到你来亲自上手,简单操作一下这些数据结构了哟,需要使用到的函数都在下面的相关知识里~
需要认真学习以下函数:
c()
: 用来建立向量的函数;
seq()
: 该函数用于创建包含from~end数值的向量;
rep()
: 该函数用来创建保存重复值的向量;
length()
: 用来计算向量长度的函数;
names()
: 该函数用来对向量各元素命名。
R拥有许多用于存储数据的对象类型,包括标量、向量、矩阵、数组、数据框和列表。它们在存储数据的类型、创建方式、结构复杂度,以及用于定位和访问其中个别元素的标记等方面都会有所不同。
是不是感觉在风中凌乱。。。这么多数据结构,都有啥区别呀!看看下图,你也许就会对各种数据结构有一个更直观的印象了。
让我们从向量开始,逐个探究每一种数据结构吧。
向量
是用于存储数值型、字符型或逻辑型数据的一维数组
。我们可以用函数c()
来创建向量。比如:
a <- c(1,2,3,4,6,7,9,0)
b <- c("哎","哟","喂")
c <- c(TRUE, TRUE, TRUE,TRUE)
仔细看看,发现了什么?
怎么每一个向量中的数据好像都是相同类型的?没错没错!记住!
同一向量中无法混杂不同模式的数据!
:
运算符是向量常用的运算符,它是给懒人发明的~为什么这么说呢?
看看下边的例子吧。
哦哟哟,勤快的人敲的好辛苦,懒懒的人一个冒号就搞定了!
But!!:
运算符有个致命缺点,那就是一次只能跳一步。
怎么办?我教你一个放飞自我随意设定步长的方法吧。
用函数seq()
:
seq()
有两个参数,分别是by
和 length.out
。by
参数用来设定步长,而length.out
参数是用来设定数据段的“块数”的。
seq(2, 8, by = 1)
seq(3, 15, length.out = 5)
让我们来看看它怎么用。
注意!对于seq()
函数,不能设置这样步数的递减:
seq(10, 9.5, by=0.1)
只能这样递减:
seq(10, 9.5, by=-0.1)
最后一个seq()
函数
seq(10, 1, length.out = 5)
给我们返回了5
个数值10.00 7.75 5.50 3.25 1.00
,他们的步长是-2.25
。
看出来了吧,R
可以均匀的帮我们按length.out
的值把数值切开。
还有一个让向量操作更方便的函数,叫rep()
函数,它就像我们的赋值粘贴功能,让你的向量想复制多少次,就复制多少次。
例一:
rep(c('男神大人'), 3)
运行结果为:
"男神大人" "男神大人" "男神大人"
例二:
rep(c(1:3), 4)
运行结果为:
1 2 3 1 2 3 1 2 3 1 2 3
其实,向量之间也是可以运算的。比如下面这样:
两个向量长度相等时,向量间的运算是相应位置的数字进行运算,运算后结果返回原位置。
但如果长度不相等呢?看看~警告我们了。
Warning message:长的对象长度不是短的对象长度的整倍数
哈哈,我们无视警告~因为。。。它还是老老实实算出来了。看下图就明白了!
原来,我们的短向量,被硬生生拉长了,难为它了。
最后,对于向量化计算,还有一个原则就是,避免使用for
循环。为什么这么说呢,因为for
循环会有明显效率不足的缺点。执行起来比向量化计算的方法慢得多。for
循环我们以后会讲到。
通过在[]
中给出元素所在位置的数值,我们就可以访问向量中的元素了哟,给你们总结下,有4种访问方式,看下图:
示例如下:
当向量非常长,我们又想知道向量长度的时候,你可以用length()函数来统计向量长度。比如:
x <- c("a", "b", "c")
length(x)
运行结果为
3
我们还可以对向量中各元素进行命名:
当然我们也可以使用元素的名称访问向量中的元素。
与命名元素类似,我们也可以使用names()函数来查看向量中某个指定元素的名称。例如:
names(x) [2]
查看向量第二个元素的名称,输出为"seo"
。
a <- c('你', '不是', '女王大人','他', '是', '好宝宝')
#----start----
#请用length函数计算向量a的长度
length(a)
#请输出“女王大人”
a[3]
#请输出“你” “是” “好宝宝”
a[c(1,5,6)]
#既然是好宝宝了,请使用rep函数,叫我三声“女王大人”
rep(a[3], 3)
#请为向量a的每个元素命名,名称依次为1,2,3,4,5,6,并输出a
names(a) <- c("1", "2", "3", "4", "5", "6")
a
#使用seq函数,将1~100分成8个元素的等差数列
seq(1, 100, length.out=8)
#-----end-----
我会介绍R语言中的矩阵,也会顺便介绍一些常用的功能函数。然后,就轮到你来亲自上手,简单操作一下这些数据结构了哟,需要使用到的函数都在下面的相关知识里~
需要认真学习以下函数:
matrix()
: 用来建立矩阵的函数;
nrow()
:求矩阵的行数;
ncol()
: 求矩阵的列数;
dim()
: 求对象的维数;
t()
: 求矩阵的转置矩阵;
solve()
: 从方程a%*%x = b中求x。若不指定b, 则求a的逆矩阵。
R
中的矩阵与数学中的矩阵一样,由指定的行(row)
与列(column)
构成。
和向量一样,矩阵也只能保存同种数据类型的数据。
比如矩阵中的所有元素可以都是数值型的,但不能“第一列是数值、第二列是字符串”。
创建矩阵
那我们先来举个例子,看看最基本的矩阵怎么创建吧。
大家可以看见,我给出了矩阵值和行数,R
就能按列填充出一个矩阵出来~
我们给出的数据个数,要等于想要建立矩阵的元素个数才可以。
不然会出现上图所提示的错误哟。
没有行名和列名看上去实在是不爽,我们可以使用函数rownames()
和colnames()
为矩阵指定行名和列名。比如指定行名:
下图中可以看见,当没有行名时,我们用rownames()
查看行名,会返回NULL
。
如何访问矩阵中的数据
借助索引 或 行名与列名,就可以访问矩阵中的数据。
在这里举个简单的例子,仔细琢磨哟,通过行名与列名访问和通过索引向量访问我们会放在练习中。
与向量类似哟,如果索引是负数,则表示排除指定行或列;若索引为向量,则可以从矩阵中一次获取多个值。若想获取整行或整列,只要在指定行或列的位置上不写索引即可。
矩阵与标量、矩阵与矩阵间的四则运算如下表所示:
除了简单的四则运算,矩阵还有特殊的运算需要函数来帮忙。
若不指定b,则求 a的逆矩阵。
#----start----
#创建3*3矩阵x,包含元素c(1,3,4,2,-9,4,7,0,8),并输出x
x <- matrix(c(1,3,4,2,-9,4,7,0,8), nrow = 3)
x
#获取第一行、第三行与第1列、第三列数据的交集
x[c(1, 3), c(1, 3)]
#为矩阵x的行和列设置名称,并输出x
#行名分别为“Lisa”“Bob”“Jay”
#列名分别为“成绩1”“成绩2”“成绩3”
rownames(x) <- c("Lisa", "Bob", "Jay")
colnames(x) <- c("成绩1", "成绩2", "成绩3")
x
#请使用行名、列名查出Bob的成绩2
x["Bob", "成绩2"]
#使用solve()函数,求指定矩阵的逆矩阵
#然后使逆矩阵与原矩阵相乘,查看得到的结果是否为单位矩阵
x <- matrix(c(1, 2, 3, 4),ncol=2)
y = solve(x)
y
z = x %*% y
z
#将3*2的矩阵x改为2*3,并输出矩阵x
x <- matrix(c(1,3,4,2,-9,4), ncol=2)
y <- matrix(x, nrow = 2)
y
#-----end-----
我会介绍 R 语言中的数组,也会顺便介绍一些常用的功能函数。然后,就轮到你来亲自上手,简单操作一下这些数据结构了哟,需要使用到的函数都在下面的相关知识里
需要认真学习以下函数:
array()
: 用来建立数组的函数;
dim()
: 求对象的维数。
由上图可以看出,数组(array)
与矩阵类似,但是维度可以大于2
。
比如,使用矩阵可以表现 2×3 维的数据,而使用数组则可以表现 2×3×4 维的数据。
和向量、矩阵一样,数组也只能保存同种数据类型的数据。
创建数组:
那我们先来举个例子,看看3×4的数组和2×3×3维的数组是怎么创建吧。
对于2×3×3维的数组,你们也可以理解为,它创造了3 个 2×2的矩阵。
我们给出的数据个数,要等于想要建立数组的元素个数才可以。
最简单的方法,就是把所有维数乘起来,就是你的元素个数哟~
访问数组中数据的方法和矩阵类似,因为他们只是维数不同而已。
所以,要想访问数组元素,我们一样可以使用索引、名称等进行访问。
x <- array(1:12, dim=c(2, 2, 3))
x[1, 1, 1]
我们用:
x[1, 2, 3]
我们用:
x[, , 3]
与矩阵一样。我们可以使用dim()
函数获取数组的维数哟。
#----start----
#创建元素为 1:12 的 2*3*2 维数组,并输出
a <- array(1:12, dim = c(2, 3, 2))
a
#输出第1行2列且处在2维点的数据
a[1, 2, 2]
#输出该数组维数
dim(a)
#为数组的行命名,分别命名为“雅典娜”和“星矢”
#为数组的列命名,分别命名为“能量1”和“能量2”、“小宇宙能量”
rownames(a) <- c("雅典娜", "星矢")
colnames(a) <- c("能量1", "能量2", "小宇宙能量")
a
#输出星矢的小宇宙能量
a["星矢", "小宇宙能量", ]
#-----end-----
我会介绍 R 语言中的数据框,也会顺便介绍一些常用的功能函数。然后,就轮到你来亲自上手,简单操作一下这些数据结构了哟,需要使用到的函数都在下面的相关知识里~
需要认真学习以下函数:
data.frame()
: 用来建立数据框的函数;
str()
: 查看数据框结构。
由于不同的列可以包含不同模式(数值型、字符型)的数据,数据框的概念跟矩阵相比更为一般。
数据框将是你在
R
中最常处理的数据结构。
给你们看个秘密,这是EduCoder
平台上的实训数据,嘘。。。
你看,这个表里包含了数值型和字符型数据,我们没有办法为它建一个矩阵,所以,这种情况下,数据框是最好的选择。
数据框可以通过函数data.frame(col1, col2, col3, ...)
来创建。
其中列向量col1
,col2
,col3
可为任何类型。
每一列数据的模式必须唯一,不过你却可以将多个模式的不同列放到一起组成数据框。
比如执行以下代码后:
patientID <- c(1, 2, 3, 4)
age <- c(25, 34, 28, 52)
diabetes <- c("type1", "type2", "type1", "type1")
status <- c("Poor", "Improved", "Excellent", "Poor")
patientdata <- data.frame(patientID, age, diabetes, status)
patientdata
我们可以像之前一样使用索引来访问数据框中的元素,也可以用数据框特有的新办法来访问,那就是$
符号。
举个例子来看看吧:
patientdata[1:2]
patientdata[c("diabetes", "status")]
patientdata$age
得到的结果是:
$
符号被用来选取一个给定数据框中的某个特定变量。它还有个很好用的用法,就是通过符号$
,我们可以用列名做联表!
我们也可以将不存在的列w
,添加到数据框patientdata
上。
patientdata$w <- c("A", "B", "C", "D")
str()
可以查看数据框结构,可以轻松得知各列保存着哪种类型的数据。比如查看我们刚才用过的糖尿病人的数据结构:diabetes
列和status
列都是因子(factor)
列。因子我们会在下一节中讲到~names()
函数用于返回数据框点的列名。使用 %in%
运算符与names()
函数,能够快速选取特定列。b
拥有a
、b
、c
三个列,使用:d[ ,names(d)%in%c("b","c")]
只选取并输出b
、c
列。
反之~使用!
运算符可以排除特定列,很好用哇!
我们就这样得到了列a
。细心的同学可能要喊不对了~怎么列a
变成了向量
呢,我的数据框呢?
这是因为,列是一维时,返回值与相应列的数据类型不同。想避免这种类型转换的话,只需要设置drop=FALSE
即可:
#----start----
#建立一个两列的数据框,列名分别为 ”x“ 和 ”y“ , 并输出该数据框
# x 的元素是 c(1,2,3,4,5),y 的元素是 c(2,4 6 8 10)
x <- c(1,2,3,4,5)
y <- c(2,4, 6, 8, 10)
a <- data.frame(x, y)
a
#查看该数据框结构
str(a)
#以非向量的形式读出数据框的 x 列
a[ ,names(a)%in%c("x"), drop=FALSE]
#将数据框中 x 列的值由1,2,3,4,5换成6,7,8,9,10,并输出数据框
a[1] <- c(6,7,8,9,10)
a
#再往该数据框中添加新列 ”z“,包含元素”A“,"B","C","D","E", 并输出新的数据框
a$z <- c("A","B","C","D","E")
a
#用运算符 %in% 输出 y、z 列 与第一、二行
b = a[ ,names(a)%in%c("y","z")]
b[1:2,]
#-----end-----
我会介绍R语言中的因子,也会顺便介绍一些常用的功能函数。然后,就轮到你来亲自上手,简单操作一下这些数据结构了哟,需要使用到的函数都在下面的相关知识里~
需要认真学习以下函数:
factor()
: 用来建立因子的函数;
nlevels()
: 返回因子中的水平个数;
levels()
: 返回因子水平目录;
ordered()
: 创建有序因子。
因子
在很多书上都将的很学术,让人感觉云里雾里的,其实呢,简单来说,在 R
中,因子
就是分类数据
。
比如说,狗狗可以分类成“大型犬”“中型犬”“小型犬”,那“狗狗”就是顺序型
的因子
,它有3种水平(level)
,分别是“大型犬”“中型犬”“小型犬”。
那还有一些因子其实是无法比较大小的,我们叫它名义型
的因子
,比如政治倾向中的2种level
,“左派”和“右派”。
性别属于名义型数据,有“m”
(male
,男性)与“f”
(female
,女性)两种可能的值。下面的例子中,创建了性别的因子
,保存了男性的变量在sex
中。
sex <- factor("m", c("m","f"))
sex
该因子可以包含值的水平被限制为“m”
和 “f”
。输出为下图:
我们用函数levels()
可以获得因子水平的名称。
levels()
返回的是向量,所以咯,我们可以用索引获得各水平值。
我们还可以修改因子变量中的水平值,嗯,还是用levels()
函数啊!
比如:我们把“m”
修改为“male”
。
比如:
不错,女士优先!我把女士放前边了,大家能看到结果中,“female”
在“male”
的前边,哈哈!
#----start----
#读取学生在作业1737中的表现
choice <- read.csv('user_choice_1737.csv')
#查看数据框choice的数据结构
str(choice)
#学生们的选择题答案存在了choice_position列里,查看choice_position里的因子水平名称
stu <- choice[ ,names(choice)%in%c("choice_position")]
postion <- factor(stu)
levels(postion)
ordered(postion,c("B","A","C","D"))
#choice_position里的因子水平分别是A,B,C,D,但是选B选项的人最多
#请按B,A,C,D的顺序给因子水平排序,并输出choice$choice_position
#-----end-----
我会介绍R语言中的列表,也会顺便介绍一些常用的功能函数。然后,就轮到你来亲自上手,简单操作一下这些数据结构了哟,需要使用到的函数都在下面的相关知识里~
需要认真学习以下函数:
list()
: 用来建立列表的函数。
列表(list)
是R
的数据类型中最复杂的一种。它可以包罗万象,什么都存!
某个列表中可能是若干向量、矩阵、数据框,甚至其他列表的组合。
R
中的列表与其他语言中的散列表(Hash table)
或字典(Dictionary)
非常类似,就是说,列表是以(键,值)
对的形式保存数据的关联数组(Associative Array
)。
那我们先来举个例子,看看列表是怎么创建的吧。
x <- list(name="foo", heigth=70)
得到的结果是:
该列表有2个成分,一个字符串和一个标量。
再复杂一点:
list(a=list(val=c(1,2,3)), b=list(val=c(1,2,3,4)))
看看得到什么样的结果:
列表嵌套列表哟!
访问列表中的数据,我们既可以使用索引又可以使用对象名。
输出列表时,其中的每个对象都会以$name
的形式罗列出来。使用x$name
形式可以访问对象的数据。
举个例子:
x <- list(name="foo", height=c(1, 3, 5))
x$name
x$height
返回结果是:
恩~有很多小伙伴可能看到x[n]
和x[[n]]
觉得很困惑,长得差不多,多一个括号会有多大的不同呢?
那我告诉你哟,x[n]
返回的是(name, value)
的子列表,不是value
!
而x[[n]]
返回的是对象的value
!
看个例子你就懂了:
x <- list(name="foo", height=c(1, 3, 5))
x[1]
x[[1]]
#----start----
#创建一个列表,该列表有4个对象,分别是g、h、j、k
#其中对象 g 的 name 为 title,对象 h 的 name 为 ages,其他对象没有 name
#g 为 标量字符串“My First List”
#h 为数值向量,包含元素 25,26,18,39
#j 为 5*2 的矩阵,元素为1:10
#k 为字符串向量,包含元素 “one”,“two”,“Three”
#输出该列表
list1 <- list(title="My First List",
ages=c(25,26,18,39),
matrix(1:10, nrow=5),
c("one","two","Three"))
list1
#输出该列表的第二个对象的 value
list1[[2]]
#输出该列表第三个对象
list1[3]
#输出“ages”的value
list1$ages
#-----end-----