-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathdata-structure.Rmd
293 lines (214 loc) · 9.99 KB
/
data-structure.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
# 数据结构 {#chap-data-structure}
```{r, echo=FALSE}
library(data.table)
```
网站 <https://r-coder.com/> 主要介绍 Base R,特点是全面细致,排版精美
> 可用于绘图的数据对象,向量 vector 等,只涉及基础操作和绘图,关键在入门引导式的介绍,点到即止
数据类型:字符、数值:字符数据操作:按数据类型介绍各类数据操作,重复之处如前所述,数据处理的分类:按数据类型来,一共是 table matrix data.frame 和 vector
> The trouble with nonstandard evaluation is that it doesn't follow standard evaluation rules...
>
> --- Peter Dalgaard (about nonstandard evaluation in the `curve()` function) R-help (June 2011)
<!-- 详细介绍 data.frame 和 data.table,而不简略介绍 tibble 和 dplyr -->
向量,列表,
数据框 data frame 在 R 里面可以用三种不同类型的数据对象来表达
> 从历史脉络来看,为什么会出现三种不同的东西,它们之间的区别和联系是什么,能否用一张表来描述
data.frame 设计的历史,首次包含在 R 里面是什么时候,R 是否一发布就包含了这个数据类型
The function `data.frame()` creates data frames, tightly coupled collections of variables which share many of the properties of matrices and of lists, used as the fundamental data structure by most of R's modeling software.
**data.table** 2006 年 4 月 15 日首次登陆 CRAN 发布 1.0 版本,差不多恰好 10 年后
**tibble** 在 2016 年 3 月 23 日首次登陆 CRAN 发布 1.0 版本
`data.frame()`, `tibble()` 和 `data.table()` 的区别,去看函数的帮助文档
Provides a 'tbl_df' class (the 'tibble') that provides stricter checking and better formatting than the traditional data frame.
[vctrs](https://github.com/r-lib/vctrs) 和 [rlang](https://github.com/r-lib/rlang) 包 R 内置的 [R Language Definition](https://cran.r-project.org/doc/manuals/r-release/R-lang.html)
## 类型 {#subsec:typeof}
```{r}
x <- "abc" # 数据对象
typeof(x) # 数据类型
mode(x) # 存储模式
storage.mode(x) # 存储类型
```
| 符号 | 含义 |
|:--------------|:------------------------|
| `NULL` | 空值 |
| `symbol` | 可变的名称/变量 |
| `pairlist` | pairlist 对象\*\*\* |
| `closure` | 函数闭包 |
| `environment` | 环境 |
| `promise` | 实现惰性求值的对象 |
| `language` | R 语言构造 |
| `special` | 内部函数,不计算参数 |
| `builtin` | 内部函数,计算参数 |
| `char` | scalar 型字符对象\*\*\* |
| `logical` | 逻辑向量 |
| `integer` | 整数向量 |
| `double` | 实值向量 |
| `complex` | 复值向量 |
| `character` | 字符向量 |
| `...` | 可变长度的参数\*\*\* |
| `any` | 匹配任意类型 |
| `expression` | 表达式对象 |
| `list` | 列表 |
| `bytecode` | 位代码\*\*\* |
| `externalptr` | 外部指针对象 |
| `weakref` | 弱引用对象 |
| `raw` | 位向量 |
| `S4` | S4 对象 |
: (#tab:all-data-type) 函数 `typeof()` 返回的数据类型 [^data-structure-1]
[^data-structure-1]: 表格中带 \*\*\* 标记的类型,用户不能轻易获得
| Value | R vector | Rcpp vector | Rcpp matrix | Rcpp scalar | C++ scalar |
|:---------:|:---------:|:-------------:|:-------------:|:---------:|:---------:|
| Logical | `logical` | `LogicalVector` | `LogicalMatrix` | \- | `bool` |
| Integer | `integer` | `IntegerVector` | `IntegerMatrix` | \- | `int` |
| Real | `numeric` | `NumericVector` | `NumericMatrix` | \- | `double` |
| Complex | `complex` | `ComplexVector` | `ComplexMatrix` | `Rcomplex` | `complex` |
| String | `character` | `CharacterVector` (`StringVector`) | `CharacterMatrix` (`StringMatrix`) | `String` | `string` |
| Date | `Date` | `DateVector` | \- | `Date` | \- |
| Datetime | `POSIXct` | `DatetimeVector` | \- | `Datetime` | `time_t` |
: (#tab:basic-data-type) R/Rcpp 提供的基本数据类型
## 字符 {#sec-character}
## 向量 {#sec-vector}
## 矩阵 {#sec-matrix}
## 数组 {#sec-array}
更多数组操作 [rray](https://github.com/r-lib/rray)
## 表达式 {#sec-expression}
```{r}
# %||% 中缀符
# x 是空值或者长度为 0 则保留 y 否则保留 x
function(x, y) if (is.null(x) || length(x) == 0) y else x
```
## 列表 {#sec-list}
```{r}
x <- list(a = 1, b = 2, c = list(d = c(1, 2, 3), e = "hello"))
print(x)
base::print.simple.list(x)
```
## 日期 {#sec-date}
注意观察时间转化
```{r}
Sys.Date()
Sys.time()
c(Sys.time(), Sys.Date())
data.table::year(Sys.Date())
data.table::year(Sys.time())
data.table::year(c(Sys.time(), Sys.Date()))
```
```{r}
x <- Sys.time()
class(x)
format(x, format = "%Y-%m-%d")
```
```{r}
x <- c("2019-12-21", "2019/12/21")
data.table::year("2019-12-21")
data.table::year("2019/12/21")
```
但是,下面这样会报错
```{r,error=TRUE}
data.table::year(x)
```
正确的姿势是首先将表示日期的字符串格式统一
```{r}
gsub(pattern = "/", replacement = "-", x) |>
data.table::year()
```
date-times 表示 POSIXct 和 POSIXlt 类型的日期对象
```{r}
(x <- Sys.time())
class(x)
data.table::second(x) # 取秒
format(x, format = "%S")
data.table::minute(x) # 取分
format(x, format = "%M")
data.table::hour(x) # 取时
format(x, format = "%H")
data.table::yday(x) # 此刻在一年的第几天
data.table::wday(x) # 此刻在一周的第几天,星期日是第1天,星期六是第7天
data.table::mday(x) # 此刻在当月第几天
format(x, format = "%d")
weekdays(x)
weekdays(x, abbreviate = T)
data.table::week(x) # 此刻在第几周
data.table::isoweek(x)
data.table::month(x) # 此刻在第几月
format(x, format = "%m")
months(x)
months(x, abbreviate = T)
data.table::quarter(x) # 此刻在第几季度
quarters(x)
data.table::year(x) # 取年
format(x, format = "%Y")
```
::: {.rmdtip data-latex="{提示}"}
`format()` 是一个泛型函数,此刻命名空间有 `r length(methods(format))` 方法。 `format.Date()`, `format.difftime()`, `format.POSIXct()` 和 `format.POSIXlt()` 四个函数通过格式化不同类型的日期数据对象抽取指定部分。
```{r}
format(difftime(Sys.time(), x, units = "secs"))
```
日期转化详见 [@Brian_2001_date; @Gabor_2004_date]
:::
上个季度最后一天
```{r}
# https://d.cosx.org/d/421162/16
as.Date(cut(as.Date(c("2020-02-01", "2020-05-02")), "quarter")) - 1
```
本季度第一天
```{r}
as.Date(cut(as.Date(c("2020-02-01", "2020-05-02")), "quarter"))
```
类似地,本月第一天和上月最后一天
```{r}
# 本月第一天
as.Date(cut(as.Date(c("2020-02-01", "2020-05-02")), "month"))
# 上月最后一天
as.Date(cut(as.Date(c("2020-02-01", "2020-05-02")), "month")) - 1
```
**timeDate** 提供了很多日期计算函数,比如季初、季末、月初、月末等
```{r,eval=FALSE}
library(timeDate)
# 季初
as.Date(format(timeFirstDayInQuarter(charvec = c("2020-02-01", "2020-05-02")), format = "%Y-%m-%d"))
# 季末
as.Date(format(timeLastDayInQuarter(charvec = c("2020-02-01", "2020-05-02")), format = "%Y-%m-%d"))
# 月初
as.Date(format(timeFirstDayInMonth(charvec = c("2020-02-01", "2020-05-02")), format = "%Y-%m-%d"))
# 月末
as.Date(format(timeLastDayInMonth(charvec = c("2020-02-01", "2020-05-02")), format = "%Y-%m-%d"))
```
`cut.Date()` 是一个泛型函数,查看它的所有 S3 方法
```{r}
methods(cut)
```
格式化输出日期类型数据
```{r}
formatC(round(runif(1, 1e8, 1e9)), digits = 10, big.mark = ",")
```
```{r}
# Sys.setlocale(locale = "C") # 如果是 Windows 系统,必须先设置,否则转化结果是 NA
as.Date(paste("1990-January", 1, sep = "-"), format = "%Y-%B-%d")
```
获取当日零点
```{r}
format(as.POSIXlt(Sys.Date()), "%Y-%m-%d %H:%M:%S")
```
从 POSIXt 数据对象中,抽取小时和分钟部分,返回字符串
```{r}
strftime(x = Sys.time(), format = "%H:%M")
```
| 代码 | 含义 | 代码 | 含义 |
|-----------|:-----------------|-----------|:------------------------------|
| `%a` | Abbreviated weekday | `%A` | Full weekday |
| `%b` | Abbreviated month | `%B` | Full month |
| `%c` | Locale-specific date and time | `%d` | Decimal date |
| `%H` | Decimal hours (24 hour) | `%I` | Decimal hours (12 hour) |
| `%j` | Decimal day of the year | `%m` | Decimal month |
| `%M` | Decimal minute | `%p` | Locale-specific AM/PM |
| `%S` | Decimal second | `%U` | Decimal week of the year (starting on Sunday) |
| `%w` | Decimal Weekday (0=Sunday) | `%W` | Decimal week of the year (starting on Monday) |
| `%x` | Locale-specific Date | `%X` | Locale-specific Time |
| `%y` | 2-digit year | `%Y` | 4-digit year |
| `%z` | Offset from GMT | `%Z` | Time zone (character) |
: (#tab:table-of-date) 日期表格
本节介绍了 R 本身提供的基础日期操作,第\@ref(chap-time-series-analysis)章着重介绍一般的时间序列类型的数据对象及其操作。
## 空值 {#sec-null}
移除`list()` 列表里的为 `NULL` 元素
```{r}
rm_null <- function(l) Filter(Negate(is.null), l)
```