第一讲 R语言起步 TEST Ver.

Author

谁课仕西格玛

Published

2023-09-25

大家好,这里是谁课仕西格玛,欢迎来到《R语言手把手保姆级教学之傻子都能学会》系列课程。

如果你完全零基础、毫无编程经验,但是又想学习数据分析,那么恭喜你,你来对地方了!在这部课程当中,我会把你当做一个三岁小孩儿,带领你从零开始学习R语言,由1 + 1 = 2开始(绝不骗人,真的是从字面意义上的1 + 1 = 2开始),循序渐进的带你了解R语言的美妙。

本课程遵循“易掌握难精通”的原则,重在启发你的思考,相信我你一定会像我一样,学会R语言,使用R语言,爱上R语言。

这一讲是《第一讲 R语言起步》,主要介绍R语言的下载与安装,R语言中常用的运算,以及R语言中基本的数据类型。

学习完本讲之后,你将能够在你的电脑上自主安装R语言本体和RStudio, 使用R语言计算各种常用的数学运算和逻辑运算,并对R语言中常用的数据类型有一个基本的了解。

1. R语言的下载与安装

1.1 下载R语言本体

点击下载R语言

R语言支持Windows、macOS、Linux,根据操作系统选择相应的版本。

1.2 下载RTools(仅限Windows操作系统

点击下载RTools

如果使用Windows操作系统,需要同时安装RTools。

安装RTools可以确保后续安装各种扩展包时更加顺利。

1.3 下载RStudio IDE

点击下载RStudio

与R语言本体类似,RStudio支持多种操作系统,根据操作系统选择相应的版本。

IDE是集成开发环境(Integrated Development Environment)首字母的缩写,这一步不是必须的,但安装IDE可以大幅提高编写代码的工作效率。

2. 把R语言当作计算器来使用

2.1 加减乘除

加法运算符:+

## 1加1等于2
## 是不是没骗人?;p
1 + 1
[1] 2

减法运算符:-,同时这也可以用来表示负数。

## 5减2等于3
5 - 2 
[1] 3
## -1加1等于0
-1 + 1
[1] 0

乘法运算符:*

## 二三得六
2*3
[1] 6
## 三三得九
3*3
[1] 9

除法运算符:/

## 10除以2等于5
10/2
[1] 5

混合运算根据先乘除后加减的原则,按照需要使用括号()即可。

1 + 2*3 - (4 + 5/6) + 7*8/9
[1] 8.388889

2.2 幂运算和开根号

幂运算符:^,同时这也是指数运算符。

## 3的平方等于9
3^2
[1] 9
## 2的立方等于8
2^3
[1] 8

不管你的数学老师是怎么教你的,R语言当中0的0次幂等于1。

0^0
[1] 1

开平方(square root)可以使用函数sqrt

## 9的平方根是3
sqrt(9)
[1] 3

与开平方不同,开根号没有函数可以使用,但可以使用幂运算符^,因为一个数字的立方根就等于这个数字的\(\frac{1}{3}\)次幂。

## 16的立方根
16^(1/3)
[1] 2.519842

注意此处括号的使用,数学运算当中幂函数的优先级高于除法运算,所以需要把1/3用括号括起来,否则会得到不符合预期的结果。

## 16的1次方除以3
16^1/3
[1] 5.333333

2.3 自然指数与对数运算

计算自然指数,需要使用函数exp

## e的1次方等于e本身
exp(1)
[1] 2.718282
## e的平方
exp(2)
[1] 7.389056
## 先计算e本身,再计算e的平方,结果是一样的
exp(1)^2
[1] 7.389056

对数运算可以使用函数loglog10log2,分别对应自然对数、以10为底的对数、以2为底的对数。

## e的几次方是1?0(log函数默认底数是e)
log(1)
[1] 0
## 10的几次方是100?2
log10(100)
[1] 2
## 2的几次方是16?4
log2(16)
[1] 4

除了上面展示的以e为底、以10为底、以2为底之外,可以使用log函数中的base参数指定底数。

## 5的几次方是30?
log(30, base = 5)
[1] 2.113283

2.4 除法运算中的取整和取余

## 10除以3无法整除
10/3
[1] 3.333333

除法运算中,如果不能整除,结果可以分为整数部分和余数部分,可以使用下面的运算符分别获取这两部分的值。

取整运算符:%/%
取余运算符:%%

## 10除以3的整数部分是3
10 %/% 3
[1] 3
## 10除以3的余数部分是1
10 %% 3
[1] 1

3. 逻辑运算就是尊嘟假嘟?o.O

逻辑运算的对象是TRUE(尊嘟)或者FALSE(假嘟),注意一定要全是大写,true或者True都是不对的,FALSE同理。

也可以使用首字母T或者F,但不推荐养成这种习惯,代码比较多的时候全拼相较于单一字母,表达更加清晰明确。

3.1 与或非

逻辑运算的基本运算符有三个:与&、或|、非!

运算规则:A和B均为TRUEA & B的值为TRUE,A和B任意一个为FALSEA & B的值为FALSE

TRUE & TRUE # TRUE
[1] TRUE
TRUE & FALSE # FALSE
[1] FALSE
FALSE & TRUE # FALSE
[1] FALSE
FALSE & FALSE # FALSE
[1] FALSE

运算规则:A和B均为FALSEA | B的值为FALSE,A和B任意一个为TRUEA | B的值为TRUE

FALSE | FALSE # FALSE
[1] FALSE
FALSE | TRUE # TRUE
[1] TRUE
TRUE | FALSE # TRUE
[1] TRUE
TRUE | TRUE # TRUE
[1] TRUE

如果把TRUE当作1FALSE当作0,那么与&运算就类似乘法(1*0 = 0),或|运算则类似加法(1 + 0 = 1)。

实际上,你真的可以对TRUEFALSE进行加减乘除等数学运算,在计算时TRUE会被当做1FALSE会被当做0

TRUE*FALSE # 1*0
[1] 0
TRUE + FALSE # 1 + 0
[1] 1
TRUE^2 # 1^2
[1] 1
log(FALSE) # log(0)
[1] -Inf

虽然没有人会真的用TRUEFALSE做大量的数学运算,但知道这个特性,在一些特定的场合会特别有用,后续的课程学习中会给出具体的例子。

运算的规则非常简单,!TRUE就是FALSE!FALSE就是TRUE

3.2 比较大小

TRUEFALSE通常会是两个值大小比较的输出结果,而非上面示例中那样通过手动输入,例如1 < 2会输出TRUE3 > 5则会输出FALSE

常用的比较大小的运算符包括:小于<、小于等于<=、大于>、大于等于>=
还有两个用来比较相等和不等的运算符:相等==、不等!=

1 < 2 # TRUE
[1] TRUE
3 > 5 # FALSE
[1] FALSE
10 <= 100 # TRUE
[1] TRUE
8 >= 8.0 # TRUE
[1] TRUE
log(exp(1)) == exp(1)^0 # TRUE
[1] TRUE
5 %/% 3 != 1 # FALSE
[1] FALSE

3.3 比较字符串(了解即可

字符串的比较,最常用的是相等==或不等!=

"a" == "a" # TRUE
[1] TRUE
"a" != "ab" # TRUE
[1] TRUE
"123" == "456" # FALSE
[1] FALSE

但实际上R语言当中字符串也是可以比较大小的,尽管这听起来有些违背直觉。

单一数字字符串大小的比较,就和比较数字的大小一样。

"1" > "2" # FALSE
[1] FALSE
"8" < "9" # TRUE
[1] TRUE

但是一旦超过10,数字字符串的比较就开始变得非常不可靠。

"9" < "10" # FALSE,应该是TRUE
[1] FALSE
"100" < "1000" # TRUE
[1] TRUE
"50" < "100" # FALSE,应该是TRUE
[1] FALSE

这也是为什么不推荐直接比较数字字符串的原因,如果你有两个数字字符串,且想要比较他们的大小,可以使用as.numeric函数将它们转换为数字后再进行。

as.numeric("9") < as.numeric("10") # TRUE
[1] TRUE
as.numeric("100") < as.numeric("1000") # TRUE
[1] TRUE
as.numeric("50") < as.numeric("100") # TRUE
[1] TRUE

字母大小的比较是按照字母表的顺序进行的,小写字母a最小,大写字母Z最大,相同的字母大写大于小写。

"a" < "b" # TRUE
[1] TRUE
"z" > "A" # TRUE
[1] TRUE
"a" < "A" # TRUE
[1] TRUE
"b" >= "B" # FALSE
[1] FALSE

实际上,字符串的比较是逐位进行的,在比较时会逐位判断是否相等,然后输出第一个不相等位置的字符比较结果。

"abd" > "abc" # 相当于比较"d" > "c"
[1] TRUE
"2023-10-01" < "2024-01-01" # 相当于比较"3" < "4"
[1] TRUE
"app ver. 1.0" < "app ver. 2.0" # 相当于比较"1" < "2"
[1] TRUE

再次强调,这个特性知道就好,使用时尽量避免对字符串直接进行大小的比较,因为如果字符串长度不等,可能会返回不符合预期的结果。

## app版本10.0大于app版本5.0吗?答案应该是TRUE
"app ver. 10.0" > "app ver. 5.0" # 实际结果是FALSE,相当于比较"1" > "5"
[1] FALSE

4. 认识一些新朋友

这一节会带领大家认识R语言中最常用的三种数据类型,缺失数据NA和四种数据结构,大家只需要能够分辨谁是谁即可,更多详细的内容会在下一讲中继续学习。

4.1 三种数据类型

  1. 数字类型(numeric),例如123

  2. 字符类型(character),用引号(可以是双引"或单引')包起来的一串字符,例如:

    • 比较简单的字符串:"123""abc""qwert456#"
    • 含有一个引号的字符串:'含有"双引号"的字符串'"含有'单引号'的字符串"
    • 含有多个引号的字符串:"'一个含有\"双引号\"的字符串外包含一个单引号'"

更多关于character的知识会在后续正则表达式中学习讲解

  1. 逻辑类型(logical),之前见到的TRUEFALSE都是此类型

我们可以使用函数class来判断一个数据是什么类型。

class(1234)
[1] "numeric"
class("1234")
[1] "character"
class(TRUE)
[1] "logical"

4.2 缺失数据NA

缺失数据用NANot Avaiable)表示。

如果使用class函数查看NA的类型,你会发现它是logical。

class(NA)
[1] "logical"

但这只是一种表象,假如你用逻辑运算对NA进行操作,得到的结果几乎都是NA

TRUE & NA
[1] NA
FALSE & NA
[1] FALSE
FALSE | NA
[1] NA
TRUE | NA
[1] TRUE
!NA
[1] NA

上面五个结果中,只有FALSE & NATRUE | NA返回了非NA的值,可以思考一下这是为什么。

实际上不只是逻辑运算,数学运算对NA操作得到的结果也都是NA

1 + NA
[1] NA
NA - 5
[1] NA
NA*3
[1] NA
NA/10
[1] NA
NA^2
[1] NA

你甚至无法比较两个NA的大小或两个NA是否相等,在没看答案之前,你觉得NA == NA吗?

NA > NA
[1] NA
NA < NA
[1] NA

如果真的要判断一个数值是否等于NA,我们需要使用函数is.na

is.na(NA) # TRUE
[1] TRUE
!is.na(NA) # FALSE
[1] FALSE

4.3 四种数据结构

4.3.1 vector

vector是R语言中最基础的数据结构,vector有两个特点:

  1. 可以包含1个或多个元素
  2. 每个元素必须是相同的数据类型,因此vector可以分为numerical vector、character vector、和logical vector

创建一个vector可以使用c或者vector函数,这里先简单介绍一下c

c(1, 2, 3, 4, 5)
[1] 1 2 3 4 5
c("a", "b", "ab")
[1] "a"  "b"  "ab"
c(TRUE, FALSE)
[1]  TRUE FALSE

如果只有一个元素,c可以省略,例如数字1就是一个仅有一个元素的vector,它与c(1)是等效的。

如果一定要把不同类型的元素混合在一起创建vector,那么所有元素都会被强制转换为相同的类型,具体的转换顺序是logical -> numeric -> character。

c(1, 2, 3, FALSE, TRUE) # FALSE和TRUE会被转换为numeric
[1] 1 2 3 0 1
c(FALSE, "123", "ab") # FASLE会被转换为character
[1] "FALSE" "123"   "ab"   
c(100, "x", "y") # 100会被转换为character
[1] "100" "x"   "y"  
c(50, "abc", TRUE) # 50和TRUE会被转换为character
[1] "50"   "abc"  "TRUE"

重点:vector当中的元素必须是相同的数据类型。

4.3.2 matrix

matrix简单说就是二维的vector,它不再是个一维的向量,而是二维的矩阵(学过线性代数的都懂)。

创建一个matrix需要使用matrix函数。

matrix(1:9, nrow = 3, byrow = TRUE)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

上面这个例子创建了一个3行3列的matrix,既然是二维的vector,它的特性与vector类似,所有的元素必须都是相同的数据类型

在创建上面这个matrix的时候,我们使用了一个新的符号:,这个符号可以帮助我们快速的创建连续的numerical vector,例如我们可以使用1:100创建从数字1到数字100的vector,而无需手动输入100个数字。

1:100
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
 [19]  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
 [37]  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
 [55]  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
 [73]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
 [91]  91  92  93  94  95  96  97  98  99 100

也适用于负数或从大到小的numerical vector。

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

同样是二维数据结构,data frame的使用频率要远高于matrix,因此后续的学习重点也会主要集中在data frame上,matrix在本讲当中只需要认识即可。

4.3.3 data frame

与matrix不同,data frame允许不同列之间存在不同的数据类型,但每一列的数据类型必须是唯一的。

创建一个data frame可以使用函数data.frame

data.frame("第1列" = 1:5,
           "第2列" = c("a", "b", "c", "d", "e"),
           "第3列" = c(TRUE, FALSE, TRUE, FALSE, TRUE))
  第1列 第2列 第3列
1     1     a  TRUE
2     2     b FALSE
3     3     c  TRUE
4     4     d FALSE
5     5     e  TRUE

可以看到在上面这个例子中,我们创建了一个data frame,它的第1列是numerical类型,第2列是character类型,第3列是logical类型。

我们也可以使用函数as.data.frame将一个matrix转成data frame。

as.data.frame(matrix(1:9, nrow = 3, byrow = TRUE))
  V1 V2 V3
1  1  2  3
2  4  5  6
3  7  8  9

在实际的数据分析工作当中,很少需要手动创建data frame,更多的是由外部数据读取进来的,例如同事发来的Excel文件,或者系统下载的csv文件,或者写SQL得到的数据等等。

后续我们会花费大量篇幅介绍data frame的各种特点和操作,它将会是你使用最多的R语言数据结构,没有之一,这一讲只需要记住它与matrix的区别即可。

4.3.4 list

最后一个常用的数据结构是list,它乍看之下像一个vector,因为它是一维的,但它与vector最大的区别在于它的每个元素都可以是任意数据类型(或数据结构),所以再多看一眼,它就会爆炸……

划重点:任意数据类型(或数据结构)

这意味着什么呢?意味着一个list可以包罗万象,它可以包含目前为止讲过的所有东西,甚至包含一个list,没错,一个list当中可以包含另一个list,而那个list又可以包含任意数据类型或数据结构……相当于无限套娃。

创建一个list可以使用list函数。

list("第1个元素" = 1:10, # a numerical vector
     "第2个元素" = matrix(1:9, nrow = 3, byrow = TRUE), # a matrix
     "第3个元素" = data.frame("第1列" = 1:5,
                              "第2列" = c("a", "b", "c", "d", "e"),
                              "第3列" = c(TRUE, FALSE, TRUE, FALSE, TRUE)), # a data frame
     "第4个元素" = c("abcdefg", "12345"), # a charactor vector
     "第5个元素" = list("第5.1个元素" = 1,
                        "第5.2个元素" = "a",
                        "第5.3个元素" = TRUE) # a list
     )
$第1个元素
 [1]  1  2  3  4  5  6  7  8  9 10

$第2个元素
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

$第3个元素
  第1列 第2列 第3列
1     1     a  TRUE
2     2     b FALSE
3     3     c  TRUE
4     4     d FALSE
5     5     e  TRUE

$第4个元素
[1] "abcdefg" "12345"  

$第5个元素
$第5个元素$第5.1个元素
[1] 1

$第5个元素$第5.2个元素
[1] "a"

$第5个元素$第5.3个元素
[1] TRUE

list可以说是R语言常用的4种数据结构当中最复杂也最灵活的一个,后续也会有专门针对list的学习讲解。

4.3.5 总结

  • vector,一维,所有元素必须是相同类型
  • matrix,二维,所有元素必须是相同类型
  • data frame,二维,不同的列可以是不同类型,但每一列的元素都必须是相同类型
  • list,一维,所有元素都可以是不同类型

下一讲,我们会针对这四类常用的数据结构的特点和操作展开深入的讨论。下次课再见,拜拜!