forked from yufree/notes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
03-DSRLanguage.Rmd
413 lines (333 loc) · 12.1 KB
/
03-DSRLanguage.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# R语言编程
## R语言概述
- R语言是S语言的一种方言
- 1976年S是John Chambers等在贝尔实验室作为Fortran的扩展库开发出来的
- 1988年用C语言重写 S3方法 白皮书
- 1993年StatSci从贝尔实验室获得S语言的独家开发售卖许可
- 1998年S4方法 绿皮书 之后S语言稳定 获得Association for Computing Machinery’s Software System Award
- 2004年Insightful(原StatSci)从Lucent收购了S语言
- 2006年Alcatel收购了Lucent成立Alcatel-Lucent
- 2008年TIBCO收购Insightful 之前Insightful开发并售卖S-PLUS
- 1991年Ross Ihaka与Robert GentlemanNew在Zealand开发了R
- 1993年发布R第一份许可
- 1995年R作为自由软件发放GUN许可
- 1996年R邮件列表创立
- 1997年R Core成立 控制R源码
- 2000年R version 1.0.0 放出
- 2013年R version 3.0.2 放出
- R由CRAN掌控的base包与其他包组成
- 其余参考[R主页](http://www.r-project.org/)
## 获得帮助
```{r,eval=FALSE}
help()
?command
# 提问给出以下信息
version
str(.Platform)
```
## 数据类型及基本运算
- 所有数据都是对象 所有对象都有类型
- 基本类型包括:字符“” 数字 整数L 复数(`Re`实部 `Im`虚部) 逻辑
- 向量储存同一类型数据
- list存储不同类型数据 `[[*]]`引用相应向量 `unlist` 可用做紧凑输出
- 对象可以有属性`attributes`
- 对象赋值符号为 <- 赋值同时展示加括号或直接输入对象名 可累加赋值 `a <- b <- c`
- `#`表示注释 不执行
- `:` 用来产生整数序列 也可以用`seq`生成
- 向量用`c`产生
- 空向量用`vector()`函数建立
- 向量中类型不同的对象元素会被强制转换为同一类型 字符优先级最高 其次数字 其次逻辑(0 or 1) 也可以用来串联字符
- 可使用`as.*`来强制转化数据类型
- 对象可以用`names`命名
- 变量名开头不能是数字和. 大小写敏感 下划线不要出现在名字里 分割用. 变量名中不能有空格
- 保留字符
```{r,eval=FALSE}
FALSE Inf NA NaN NULL TRUE break else for function if in next repeat while
```
- 清空`rm(list = ls())`
- 矩阵
- 带有`dimension`属性的向量为矩阵 矩阵的生成次序为upper-left
- `matrix(1:6,nrow=2,ncol=3)`表示建一个2行3列矩阵 从1到6 先列后行赋值 可用 `byrow = T` 来更改
- 可用`c`给`dim`赋值行和列数 这样可把一个向量转为一个矩阵 `m<-1:6;dim(m)<-c(2,3)`
- 矩阵可以用`rbind`或`cbind`生成
- `t`对矩阵转置
- 因子变量表示分类数据 用标签名区分 用`level`来命名排序 默认是字母排序 有些函数对顺序敏感可用 `levels = c()` 来命名 ( 例如低中高的排序 ) 数字表示 `drop = T` 表示显示截取数据的水平 `nlevels`给出个数
- NaN表未定义或缺失值 NA表示无意义转换或缺失值 NaN可以是NA反之不可以 NA有数据类型 is.NaN与is.NA 可用来检验
- 数据框
- 特殊list 每个元素长度相等
- 每一列类型相同 矩阵所有数据类型相同
- 特殊属性`row.names`
- 转为矩阵`data.matrix`
- 变量名自动转化 可以不同
- 因子变量保持为字符可以用 `I` `data.frame(x,y,I(c))`
- 数组
- 表示更高维度的数据
- `dim() = c(x,y,z)` 三维数组表示一组数
- `dimnames` 给数组命名
- 数组调用如果只有一行 需要`drop = F` 否则 不会按照数组分类
- `ts` 产生时间序列对象
- `.Last.value` 引用前一个数值
- 取整数 用`round(x,n)` n表示保留几位小数
- 截取整数 `trunc`
- 开平方 `sqrt`
- 绝对值 `abs`
- 指数函数 `exp`
- 自然对数函数 `log`
- 以 10 为底的对数函数 `log10`
- 三角函数 `sin cos tan asin acos atan`
- 常用的逻辑运算符有: 大于 `>` 小于 `<` 等于 `==` 小于或等于 `<=` 大于或等于 `>=` 与 `&` 非 `!` 或`|`
- 判断向量x中是否与y中元素相等 `x %in% y` 结果返回逻辑值
- `sum` 求和 `prod` 求连乘
- `range` 给极值范围
- `duplicated` 给出有重复的值
- `unique` 给出无重复的值
- 向量操作 `union` 并集 `intersect` 交集 `setdiff` 除了交集的部分
- `rep` 用向量循环生成向量
```{r,eval=FALSE}
x <- 1:4 # puts c(1,2,3,4) into x
i <- rep(2, 4) # puts c(2,2,2,2) into i
y <- rep(x, 2) # puts c(1,2,3,4,1,2,3,4) into y
z <- rep(x, i) # puts c(1,1,2,2,3,3,4,4) into z
w <- rep(x, x) # puts c(1,2,2,3,3,3,4,4,4,4) into w
```
- 整型变量后面加上L x<-10L
- Inf代表1/0 同样1/Inf运算结果为0
## 环境/文件操作
- `getwd()` `setwd()` 设置工作目录
- `ls()` 列举环境中bianliang
- `list.files()` 或 `dir()` 列举当前目录下文件
- `args()` 列举函数默认变量
- `dir.create()` 创建文件目录 加上`recursive=T`可创建多级目录
- `file.create()` 创建文件
- `file.exists()` 检查文件是否存在
- `file.info()` 检查文件信息
- `file.rename()` 文件重命名
- `file.copy()` 文件复制
- `file.path()` 文件路径 多个文件组成多级路径
- `unlink()` 删除文件
## 截取数据
- `[]`截取数据
- 可以用`[x,y]`提取特定数值
- `[-1,-2]`可剔除第一行第二列
- `[[]]`用来从list或者frame里提取元素 类型固定 可提取序列`x[[1]][[3]]` 可部分匹配 `exact=FALSE`
- $用名字提取元素 可部分匹配
- 提取矩阵时默认只能提取向量 但可以提取1*1矩阵`x[1,2,drop=FALSE]`
- 先用`is.NA()`提取 用`!`排除 缺失值可用`is.element(x,y)`来处理很多表示NA值的数字 返回`x %in% y`的逻辑值
- 用`complete.cases()`提取有效数据用`[]`提取可用数据
- `head(x,n)` n表示从头截取多少行
- `tail(x,n)` n表示从尾截取多少行
- `subset(x,f)` x表示数据 f表示表达式
- 条件筛选中获得一个变量多个数值的数据使用 `[is.element(x,c(' ',' ',' ')),]` 或者`[x%in%c(' ',' ',' '),]` 使用`x == c( ' ' , ' ' , ' ' )` 会报错 循环查找三个变量
- `x!='t'` 可能会把空白值输入 应该使用`is.element(x,'t')`
- `ifelse(con,yes,no)` 利用条件筛选 返回yes 或者no 的值
- 支持正则表达式
## 读取数据
- `read.table` `read.csv` 读取表格 反之`write.table`
- `readLines` 读取文本行 反之`writeLines`
- `source` 读取R代码 反之`dump`
- `dget` 读取多个R代码 反之`dput`
- `load` 读取保存的工作区 反之`save`
- `unserialize` 读取二进制R对象 反之`serialize`
- `?read.table`
- 大数据读取提速
- 计算内存
- `comment.char = ""` 不扫描注释
- 设定`nrows`
- 设定`colClasses`
```{r,eval=FALSE}
initial <- read.table("datatable.txt", nrows = 100)
classes <- sapply(initial, class)
tabAll <- read.table("datatable.txt",
colClasses = classes)
```
- 使用`connections`与`file`等保存外部文件指向
## 控制结构
- `if else` 条件
```{r,eval=FALSE}
if(<condition>) {
## do something
} else {
## do something else
}
if(<condition1>) {
## do something
} else if(<condition2>) {
## do something different
} else {
## do something different
}
```
- `for‵ 执行固定次数的循环 嵌套不超过2层
```{r,eval=FALSE}
for(i in 1:10) {
print(i)
}
```
- `while` 条件为真执行循环 条件从左到右执行
```{r,eval=FALSE}
count <- 0
while(count < 10) {
print(count)
count <- count + 1
}
```
- `repeat` 执行无限循环 配合`break` 中断并跳出循环
- `next` 跳出当前循环继续执行
```{r,eval=FALSE}
for(i in 1:100) {
if(i <= 20) {
## Skip the first 20 iterations
next
}
## Do something here
}
```
- `return` 退出函数
- 避免使用无限循环 可用`apply`替代
## 函数
```{r,eval=FALSE}
f <- function(<arguments>) {
## Do something interesting
}
```
- 函数中参数默认值可用`formals()`显示
- 参数匹配
- 先检查命名参数
- 然后检查部分匹配
- 最后检查位置匹配
- 定义函数时可以定义默认值或者设为`NULL`
- 懒惰执行:只执行需要执行的语句
- `...` 向其他函数传参 之后参数不可部分匹配
## 编程标准
- 使用文本文档与文本编辑器
- 使用缩进
- 限制代码行宽 80为宜
- 限制单个函数长度
## 范围规则
- 自由变量采用静态搜索
- 环境是由数值符号对组成 每个环境都有母环境
- 函数与环境组成环境闭包
- 首先从函数环境中寻找变量
- 之后搜索母环境
- 最高层为工作区
- 之后按搜寻列表从扩展包中寻找变量
- 最后为空环境 之后报错
- 可以函数内定义函数
- S都存在工作区 函数定义一致 R存在内存 可根据需要调用函数环境
## 向量化操作
- 向量操作针对元素
- 矩阵操作也针对元素 `%*%` 表示矩阵操作
## 日期与时间
- 日期以`data`类型存储
- 时间以`POSIXct` 或 `POSIXlt` 类型存储
- 数字上是从1970-01-01以来的天数或秒数
- `POSIXct`以整数存储时间
- `POSIXlt`以年月日时分秒等信息存储时间
- `strptime` `as.Date` `as.POSIXlt` `as.POSIXct`用来更改字符为时间
## 循环
### `lapply`
- 对列表对象元素应用函数
- 可配合匿名函数使用
```{r}
x <- list(a = 1:5, b = rnorm(10))
lapply(x, mean)
x <- 1:4
lapply(x, runif, min = 0, max = 10)
x <- list(a = matrix(1:4, 2, 2), b = matrix(1:6, 3, 2))
lapply(x, function(elt) elt[,1])
```
### `sapply`
- `lapply`的精简版
- 如果结果是单元素列表 转化为向量
- 如果结果是等长向量 转化为矩阵
- 否则输出依旧为列表
```{r}
x <- list(a = 1:4, b = rnorm(10), c = rnorm(20, 1), d = rnorm(100, 5))
sapply(x, mean)
```
### `vapply`
- 类似`lapply`可用更复杂函数 返回矩阵
### `replicate`
- 用于将函数循环使用 如返回随机矩阵
### `rapply`
- 用`how`来调整输出方法 如选取某列表中类型数据进行迭代
### `apply`
- 数组边际函数 常用于矩阵的行列处理
- 行为1,列为2
- 可用`rowSums` `rowMeans` `colSums` `colMeans` 来替代 大数据量更快
```{r}
x <- matrix(rnorm(50), 10, 5)
apply(x, 1, quantile, probs = c(0.25, 0.75))
a <- array(rnorm(2 * 2 * 10), c(2, 2, 10))
apply(a, c(1, 2), mean)
```
### `tapply`
- 对数据子集(因子变量区分)向量应用函数
```{r}
x <- c(rnorm(10), runif(10), rnorm(10, 1))
f <- gl(3, 10)
tapply(x, f, mean)
```
### `by`
- 对数据按照因子变量应用函数 类似`tapply`
- 按照某个分类变量a分类求均值 `by(x[,-a],a,mean)`
### `split`
- 将数据按因子分割为列表 常配合`lapply`使用
- 类似`tapply`
- 可用来生成分组 用`drop`来删除空分组
```{r}
x <- c(rnorm(10), runif(10), rnorm(10, 1))
f <- gl(3, 10)
lapply(split(x, f), mean)
x <- rnorm(10)
f1 <- gl(2, 5)
f2 <- gl(5, 2)
str(split(x, list(f1, f2), drop = TRUE))
```
### `mapply`
- 多变量版`apply` 从多个参数范围取值 并用函数得到结果
```{r}
noise <- function(n, mean, sd) {
rnorm(n, mean, sd)
}
mapply(noise, 1:5, 1:5, 2)
#等同于如下循环
#list(noise(1, 1, 2), noise(2, 2, 2),
# noise(3, 3, 2), noise(4, 4, 2),
# noise(5, 5, 2))
```
### `eapply`
- 对环境变量应用函数 用于包
## 模拟
- 在某分布下产生随机数
- d 分布概率密度
- r 分布随机数
- p 分布累计概率
- q 分布分位数
```{r,eval=FALSE}
dnorm(x, mean = 0, sd = 1, log = FALSE)
pnorm(q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE)
qnorm(p, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE)
rnorm(n, mean = 0, sd = 1)
```
- `set.seed`保证重现性
- `sample`对数据采样
## 调试
- 三种提示 `message` `warning` `error` 只有`error`致命
- 关注重现性
- 调试工具 `traceback` `debug` `browser` `trace` `recover`
- 三思而行
## 分析代码
- 先设计 后优化
- `system.time` 计算代码运行时间 返回对象类型`proc_time`
- ‵user time` 执行代码用时
- `system time` CPU时间
- `elapsed time` 实际用时
- 在多核或并行条件下实际用时可以短于执行代码用时
- 明确知道耗时较长的函数时使用
- `Rprof` R代码要支持分析函数
- `summaryRprof`可使结果易读
- 不要与`system.time`混用
- 0.02s记录一次执行函数
- `by.total` 记录单个函数用时
- `by.self` 记录函数执行时被调用函数用时