---
title: "二、R语言语法基础"
format:
  dwsd-revealjs:
    logo: _extensions/drwater/dwsd/inst/ucaslogo.png
---

## 数据类型

### 数值型

R中的数值型数据可以是整数或浮点数。

```{r}
(x <- 10)
(y <- 1.23e-2)
(z <- pi)
```

## 数据类型

### 字符串

- R 中的字符串用引号括起来，建议用**双引号**。
- 中文编码主要有GBK编码和UTF-8编码， 可能遇到编码错误造成乱码。RStudio软件默认采用UTF-8编码，在R程序运行时字符串一般用UTF-8编码保存。

```{r}
(str <- "Hello, World!")
(str <- 'Hello, World!')
(str <- 'He was very angry, and shouted: "Stop!"')
```



## 数据类型

### 逻辑

```{r}
c(TRUE, FALSE)
```

## 特殊值

:::: columns
::: {.column width="45%"}
- `NA`: 这是最常见的NA类型，表示缺失值
- `NA_integer_`: 这是NA的整数类型
- `NA_real_`: 这是NA的实数类型
- `NA_character_`: 这是NA的字符类型
- `NA_complex_`: 这是NA的复数类型

:::

::: {.column width="45%"}
```{r}
#| echo: true
pi
NA
NA_character_
Inf
```

:::
::::

## 特殊值

在 R 中，`Inf` 代表正无穷大（positive infinity），而 `-Inf` 则代表负无穷大（negative infinity）。这些值通常出现在数学计算中，例如除以零或对负数取对数等操作可能会导致无穷大的结果。

```{r}
#| echo: true
# 正无穷大
(x <- Inf)

# 负无穷大
(y <- -Inf)

# 无穷大的运算
(a <- 5 / 0)

(b <- log(0))
```




## 变量赋值

在 R 中，可以使用 `<-` 或 `=` 运算符将值赋给变量，**建议用`<-`**。


```{r}
#| echo: true
# 使用 `<-` 运算符
(x <- 10)
(y <- "hello")

# 使用 `=` 运算符
(z = c(1, 2, 3))
```

## 变量赋值

```{r}
# 向量赋值
(vec <- c(1, 2, 3, 4, 5))

# 矩阵赋值
(mat <- matrix(1:9, nrow = 3))
```

## 变量赋值

### 数据框赋值

```{r}
#| echo: true

(df <- data.frame(
  Name = c("Alice", "Bob", "Charlie"),
  Age = c(25, 30, 35),
  Married = c(TRUE, FALSE, TRUE)
))
```
## 变量赋值

### 列表赋值

```{r}

(lst <- list(
  numbers = c(1, 2, 3),
  strings = c("a", "b", "c"),
  matrix = matrix(1:9, nrow = 3)
))
```


## 数学函数

```{r}
#| echo: true
round(pi, digits = 3)
log(10)
```
1. `abs(x)`: 返回 `x` 的绝对值
2. `sqrt(x)`: 返回 `x` 的平方根
3. `exp(x)`: 以e为底的指数函数值
4. `log(x, base)`: 以指定底数的对数函数的值，默认底数为e
5. `log10(x)`: 10为底的对数值
6. `log2(x)`: 2为底的对数值
7. `floor(x)`: 不大于`x`的最大整数
8. `ceiling(x)`: 不小于`x`的最小整数

## 数学函数

9. `sin(x)`, `cos(x)`, `tan(x)`: 返回 `x` 的正弦、余弦和正切值，其中 `x` 为弧度
10. `asin(x)`, `acos(x)`, `atan(x)`: `x` 的反正弦、反余弦和反正切值，返回弧度
11. `sinh(x)`, `cosh(x)`, `tanh(x)`: 返回 `x` 的双曲正弦、双曲余弦和双曲正切值
12. `asinh(x)`, `acosh(x)`, `atanh(x)`: 反双曲正弦、反双曲余弦和反双曲正切值
13. `round(x, digits)`: `x` 四舍五入，`digits`指定小数点后位数
14. `trunc(x)`: 返回`x`截断值，即去掉小数部分
15. `sign(x)`: 返回符号


## 统计函数

```{r}
#| echo: true
x <- c(5, 10, 15, 20, 25)
# 计算向量的平均值
mean(x)

# 计算向量的中位数
median(x)

# 计算向量的最小值
min(x)

# 计算向量的最大值
max(x)

# 计算向量的总和
sum(x)
```

## 统计函数

```{r}
#| echo: true

# 计算向量的标准差
sd(x)

# 计算向量的方差
var(x)

# 计算向量的分位数
quantile(x, probs = c(0.25, 0.5, 0.75))

# 统计向量的频数
(frequency <- table(x))
```


## 统计函数


### 执行两样本或单样本 t 检验

```{r}
#| echo: true
y <- c(3, 8, 13, 18, 23)
t.test(x, y)
```

## 统计函数

### Wilcoxon-Mann-Whitney检验

```{r}
#| echo: true

wilcox.test(x, y)
```


### [什么是 Wilcoxon-Mann-Whitney检验？](https://zhuanlan.zhihu.com/p/613524533）

## 统计函数

### 创建向量的直方图


```{r}
#| fig-width: 5
#| fig-height: 3

hist(x)
```





## 函数调用-练习

### 题目：设有一组数据集合 x 包含了一些整数，请编写R语言代码计算并输出以下指标：

- 平均值（mean）
- 中位数（median）
- 最大值（maximum）
- 最小值（minimum）
- 数据集合中所有元素的和（sum）
- 数据集合的标准差（standard deviation）
- 数据集合 x 为：x <- c(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

**要求：使用R语言编写函数，输入参数为数据集合 x，输出为以上指标的值。**




## 控制流程


### if-else 语句

```{r}
#| echo: true
x <- 10

if (x > 10) {
  print("x 大于 10")
} else {
  print("x 不大于 10")
}
```

## 控制流程


### for 循环

```{r}
#| echo: true
for (i in 1:5) {
  print(i)
}
```


## 自定义函数

### 定义函数

使用 `function` 关键字定义函数，并使用 `return` 关键字返回结果。

```{r}
#| echo: true
my_function <- function(x, y) {
  return(x + y)
}
```

### 调用函数

```{r}
#| echo: true
result <- my_function(3, 4)
print(result)
```

## 数据结构

### 向量

向量是一维数组，可以包含相同类型的元素。

```{r}
#| echo: true
(v <- c(1, 2, 3, 4, 5))
```

### 列表

列表可以包含不同类型的元素。

```{r}
#| echo: true
(l <- list(a = 1, b = "hello", c = TRUE))
```

## 数值型向量

### 什么是数值型向量？

- 在 R 中，向量是一种基本的数据结构。
- 数值型向量包含相同类型的数值元素。


### 创建数值型向量


```{r}
#| echo: true
# 使用 c() 函数创建数值型向量
(numeric_vector <- c(1, 2, 3, 4, 5))
```

## 数值型向量

### 向量运算


```{r}
#| echo: true
# 创建两个数值型向量
(vector1 <- c(1, 2, 3))
(vector2 <- c(4, 5, 6))

# 执行向量加法
(result <- vector1 + vector2)
# 执行向量乘法
(result <- vector1 * vector2)
```

## 向量运算

### 向量求和

```{r}
#| echo: true
# 创建数值型向量
vector <- c(1, 2, 3, 4, 5)

# 求和
(sum_result <- sum(vector))
```

## 向量运算

### 向量平均值

```{r}
#| echo: true
# 创建数值型向量
vector <- c(1, 2, 3, 4, 5)

# 平均值
(mean_result <- mean(vector))
```

## 运算-数值运算

- a 的平方。
- b 的立方。
- a 除以 b 的商和余数。

**要求：使用R语言编写函数，输入参数为 a 和 b，输出为上述结果。**

## 运算-逻辑运算

```{r}
all(c(FALSE, 2, 1:3, 3) > 1)
any(c(FALSE, 2, 1:3, 3) > 1)
(flag1 <- FALSE)
(flag2 <- (3 > 2))
(flag3 <- TRUE * TRUE)
(flag4 <- TRUE * FALSE)
(flag5 <- TRUE & FALSE)
(flag6 <- TRUE | FALSE)
```


## 运算-逻辑运算

- `which`

```{r}
which(c(FALSE, TRUE, TRUE, FALSE, NA))
which((11:15) > 12)
```

- `identical`

```{r}
identical(c(1, 2, 3), c(1, 2, NA))
identical(c(1L, 2L, 3L), c(1, 2, 3))
```

## 运算-字符型

- 特殊字符

```{r}
c("abc", "", 'a cat', NA, '李明', "\n")
```

- `paste`

```{r}
(users <- paste("ruser", 1:9))
paste(users, collapse = ", ")
```


## 运算-字符型

- 大小写

```{r}
letters[1:5]
toupper(letters[6:9])
tolower(month.abb)
stringr::str_to_title(c("monday", "tuesday"))
```


## 运算-字符型

- 字符串截取

```{r}
substr("Monday", 1, 3)
stringr::str_sub("Monday", 1, 3)
```

## 运算-字符型

- 类型转换

```{r}
100
as.character(100)

as.numeric(c("0100", "0101"))

sprintf('renamedfile%03d.png', c(3, 99, 100))
```


## 运算-字符型

- 字符串替换

```{r}
(mystr <- "He was wrong!")
gsub("wrong", "right", mystr)
```



## 索引

### 向量

```{r}
# 创建一个向量
vector <- c("apple", "banana", "cherry", "date")
# 访问第三个元素
vector[3]
# 访问多个元素
vector[c(2, 4)]
vector[c(2:4)]
```

## 索引

### 向量

```{r}
# 除了第2个元素
vector[-2]
# 超界
vector[100]
# 更新数据
vector[7] <- "New Data"
vector
```

## 索引

```{r}

(x <- 1:10)
x[x > 6]

x[x < 3] <- 99
x
# which
which(x > 10)
which.max(x)
which.min(x)
```

## 索引

### 列表

```{r}

# 创建一个列表
my_list <- list(
  fruit = c("apple", "banana", "cherry"),
  numbers = c(1, 2, 3, 4, 5)
)

# 访问列表中的第二个元素
my_list[[2]]
```

## 索引

### 数据框

```{r}

# 创建一个数据框
df <- data.frame(fruit = c("apple", "banana", "cherry"), quantity = c(5, 7, 3))

# 访问数据框中的第一个元素
df[1, 1]
# 第2-3行
df[2:3, ]
```

## 日期和时间

### `base` package


```{r}
as.Date("2024-01-01")
as.POSIXct(1)
as.Date(c("12/6/2022", "1/1/2023"), format = "%m/%d/%Y")
```


## 日期和时间

### `lubridate` package


```{r}
lubridate::today()

require(lubridate)
now()
ymd(c(20200321, 240404, "20181231"))
mdy(c("3-10-1998", "01-17-2018", "Feb 3, 2024"))
ymd_hms("1998-03-16 13:15:45", tz = "Asia/Shanghai")
```


## 日期和时间

### `lubridate` package

```{r}
make_date(2028, 1, 30)
as_date("2000-01-01")
as_datetime("2000-01-01", tz = "Asia/Shanghai")
as_datetime("2024-02-01 8:00:00", tz = "Asia/Shanghai")
```

## 日期和时间

### `lubridate` package

```{r}

year(today())
wday(today())
hour(now())
```


## 日期和时间

### `lubridate` package


```{r}
(x <- now())
floor_date(x, unit = "day")
floor_date(x, unit = "hour")
floor_date(x, unit = "10 minutes")
ceiling_date(x, unit = "10 minutes")
```

## 因子（factor）

### Factor是什么？

- 在R中，Factor是用来表示分类数据的特殊数据类型。
- 它将数据分成不同的水平(levels)，每个水平代表了一个类别。


## 因子（factor）

### 创建Factor

```{r}
# 创建一个Factor
gender <- factor(c("Male", "Female", "Female", "Male"))
# 查看Factor的水平
levels(gender)
# 改变Factor的水平顺序
gender <- factor(gender, levels = c("Female", "Male"))
summary(gender) # 使用Factor进行分组
as.numeric(gender) # 因子转换为纯粹的整数值
as.character(gender) # 转为字符
```


## 因子（factor）

### Label of Factor

```{r}
(x <- factor(1:12, label = month.abb))
factor(x, levels = month.abb[c(2:12, 1)])
```

### 分组

```{r}
cut(1:20, breaks = c(0, 5, 10, 15, 18, 20))
```


## 矩阵

```{r}
1:20
(A <- matrix(1:20, nrow = 4, byrow = TRUE))
(B <- matrix(1:20, nrow = 4, byrow = FALSE))
nrow(A)
ncol(B)
```

## 矩阵
### 高维矩阵

```{r}
X <- array(1:12, dim = c(3, 2, 2))
dim(C)
X[1, , ]
X[1, , 1]
```

## 矩阵

### `cbind`、`rbind`

```{r}
cbind(X[1, , ], X[2, , ], X[3, , ])
rbind(X[1, , ], X[2, , ], X[3, , ])

cbind(c(1, 2), c(3, 4), c(5, 6))
```

## 数据框（data frame）

**最主要的数据形式。**

```{r}
# 创建数据框
(df <- data.frame(
  Name = c("Alice", "Bob", "Charlie"),
  Age = c(25, 30, 35),
  Married = c(TRUE, FALSE, TRUE)
))
names(df)
colnames(df)
ncol(df)
nrow(df)
```


## 数据框（data frame）

```{r}
df[1, 1]
df[2, ]
df[, 1]
df$Age
df[["Age"]]
df[, "Age"]
```

## 数据框（data frame）

```{r}
X <- matrix(1:9, nrow = 3)
class(X)
(Y <- as.data.frame(X))
names(Y)
names(Y) <- c("colA", "colB", "colC")
```




## 欢迎讨论！{.center}

```{r}
#| results: 'asis'
#| echo: false
rmdify::slideend(
  wechat = FALSE,
  type = "public",
  tel = FALSE,
  thislink = "../"
)
```

