Chapter 4 R document processing

4.1 读取

读取数据框、查看数据框大小和数据类型

library(tidyverse)

df = read_csv('./data/六1-5班学生成绩.csv')
## Rows: 20 Columns: 6
## -- Column specification -------------------------------------------------------------------------
## Delimiter: ","
## chr (3): 班级, 姓名, 性别
## dbl (3): 语文, 数学, 英语
## 
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
dim(df) # 查看数据大小
## [1] 20  6
sapply(df, class) # 查看数据类型
##        班级        姓名        性别        语文        数学        英语 
## "character" "character" "character"   "numeric"   "numeric"   "numeric"
# str(df) # 查看数据结构
# summary(df)
# glimpse(df)

4.2 处理

# 三科成绩求和
df %>%
  mutate(sum = rowSums(across(where(is.numeric)), na.rm=TRUE)) %>%
  head(3)
## # A tibble: 3 x 7
##   班级  姓名   性别   语文  数学  英语   sum
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl> <dbl>
## 1 六1班 何娜   女       87    92    79   258
## 2 六1班 黄才菊 女       95    77    75   247
## 3 六1班 陈芳妹 女       79    87    66   232
df %>%
  mutate(sum = rowSums(across(语文:英语), na.rm=TRUE)) %>%
  head(3)
## # A tibble: 3 x 7
##   班级  姓名   性别   语文  数学  英语   sum
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl> <dbl>
## 1 六1班 何娜   女       87    92    79   258
## 2 六1班 黄才菊 女       95    77    75   247
## 3 六1班 陈芳妹 女       79    87    66   232
# 求三科成绩均值
# 方法一:rowMeans
df %>%
  mutate(mean = rowMeans(across(语文:英语), na.rm=TRUE)) %>%
  head(3)
## # A tibble: 3 x 7
##   班级  姓名   性别   语文  数学  英语  mean
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl> <dbl>
## 1 六1班 何娜   女       87    92    79  86  
## 2 六1班 黄才菊 女       95    77    75  82.3
## 3 六1班 陈芳妹 女       79    87    66  77.3
# 方法二:rowise + mean
df %>% 
  rowwise() %>%
  mutate(平均值 = mean(c(语文, 数学, 英语))) %>%
  head(3)
## # A tibble: 3 x 7
## # Rowwise: 
##   班级  姓名   性别   语文  数学  英语 平均值
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl>  <dbl>
## 1 六1班 何娜   女       87    92    79   86  
## 2 六1班 黄才菊 女       95    77    75   82.3
## 3 六1班 陈芳妹 女       79    87    66   77.3
# 方法三:唯一变量姓名分组 + mean
df %>%
  group_by(姓名) %>%
  mutate(平均值 = mean(c(语文, 数学, 英语))) %>%
  head(3)
## # A tibble: 3 x 7
## # Groups:   姓名 [3]
##   班级  姓名   性别   语文  数学  英语 平均值
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl>  <dbl>
## 1 六1班 何娜   女       87    92    79   86  
## 2 六1班 黄才菊 女       95    77    75   82.3
## 3 六1班 陈芳妹 女       79    87    66   77.3
# 方法四:唯一变量行号分组 + mean
df %>%
  group_by(a=rownames(.)) %>%
  mutate(平均值 = mean(c(语文, 数学, 英语))) %>%
  head(3)
## # A tibble: 3 x 8
## # Groups:   a [3]
##   班级  姓名   性别   语文  数学  英语 a     平均值
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl> <chr>  <dbl>
## 1 六1班 何娜   女       87    92    79 1       86  
## 2 六1班 黄才菊 女       95    77    75 2       82.3
## 3 六1班 陈芳妹 女       79    87    66 3       77.3
# 计数 / 排序行 / 排序列 / 修改列名

# 计数
df %>% count(班级) # 每个班级学生计数
## # A tibble: 5 x 2
##   班级      n
##   <chr> <int>
## 1 六1班     4
## 2 六2班     4
## 3 六3班     4
## 4 六4班     4
## 5 六5班     4
df %>% count(性别) # 男女性别计数
## # A tibble: 2 x 2
##   性别      n
##   <chr> <int>
## 1 女       14
## 2 男        6
df %>% count(班级, 性别) # 每个班级男女性别计数
## # A tibble: 9 x 3
##   班级  性别      n
##   <chr> <chr> <int>
## 1 六1班 女        3
## 2 六1班 男        1
## 3 六2班 女        2
## 4 六2班 男        2
## 5 六3班 女        3
## 6 六3班 男        1
## 7 六4班 女        2
## 8 六4班 男        2
## 9 六5班 女        4
df %>% count(语文 >=90) # 语文成绩90分以上计数
## # A tibble: 2 x 2
##   `语文 >= 90`     n
##   <lgl>        <int>
## 1 FALSE           13
## 2 TRUE             7
# 排序行
df %>% arrange(性别) %>% head(3) # 按性别排序行
## # A tibble: 3 x 6
##   班级  姓名   性别   语文  数学  英语
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl>
## 1 六1班 何娜   女       87    92    79
## 2 六1班 黄才菊 女       95    77    75
## 3 六1班 陈芳妹 女       79    87    66
df %>% arrange(语文) %>% head(3) # 按语文成绩从低到高排序行
## # A tibble: 3 x 6
##   班级  姓名   性别   语文  数学  英语
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl>
## 1 六3班 林可莉 女       72    52    72
## 2 六5班 蒙丽梅 女       72    72    64
## 3 六3班 何诗婷 女       76    53    72
df %>% arrange(desc(语文)) %>% head(3) # 按语文成绩从高到低排序行
## # A tibble: 3 x 6
##   班级  姓名   性别   语文  数学  英语
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl>
## 1 六1班 黄才菊 女       95    77    75
## 2 六2班 黄祖娜 女       94    88    75
## 3 六2班 徐雅琦 女       92    86    72
# 排序列
df %>% select(性别, 姓名, everything()) %>% head(3) # 将姓别和姓名列提前,其他列位置保存不变
## # A tibble: 3 x 6
##   性别  姓名   班级   语文  数学  英语
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl>
## 1 女    何娜   六1班    87    92    79
## 2 女    黄才菊 六1班    95    77    75
## 3 女    陈芳妹 六1班    79    87    66
df %>% relocate(性别, 姓名) %>% head(3) # 将姓别和姓名列提前,其他列位置保存不变
## # A tibble: 3 x 6
##   性别  姓名   班级   语文  数学  英语
##   <chr> <chr>  <chr> <dbl> <dbl> <dbl>
## 1 女    何娜   六1班    87    92    79
## 2 女    黄才菊 六1班    95    77    75
## 3 女    陈芳妹 六1班    79    87    66
df %>% relocate(性别, .before = 班级) %>% head(3) # 将姓别列至于班级列之前,其他列位置保存不变
## # A tibble: 3 x 6
##   性别  班级  姓名    语文  数学  英语
##   <chr> <chr> <chr>  <dbl> <dbl> <dbl>
## 1 女    六1班 何娜      87    92    79
## 2 女    六1班 黄才菊    95    77    75
## 3 女    六1班 陈芳妹    79    87    66
df %>% relocate(性别, .after = 班级) %>% head(3) # 将姓别列至于班级列之后,其他列位置保存不变
## # A tibble: 3 x 6
##   班级  性别  姓名    语文  数学  英语
##   <chr> <chr> <chr>  <dbl> <dbl> <dbl>
## 1 六1班 女    何娜      87    92    79
## 2 六1班 女    黄才菊    95    77    75
## 3 六1班 女    陈芳妹    79    87    66
# 修改列名
df %>% rename(Gender = 性别) %>% head(3) # 将性别列改为Gender,其他列名不变
## # A tibble: 3 x 6
##   班级  姓名   Gender  语文  数学  英语
##   <chr> <chr>  <chr>  <dbl> <dbl> <dbl>
## 1 六1班 何娜   女        87    92    79
## 2 六1班 黄才菊 女        95    77    75
## 3 六1班 陈芳妹 女        79    87    66
df %>% select(Gender = 性别, everything()) %>% head(3) # 将性别列改为Gender,并将该列置于第一列
## # A tibble: 3 x 6
##   Gender 班级  姓名    语文  数学  英语
##   <chr>  <chr> <chr>  <dbl> <dbl> <dbl>
## 1 女     六1班 何娜      87    92    79
## 2 女     六1班 黄才菊    95    77    75
## 3 女     六1班 陈芳妹    79    87    66
df %>% relocate(Gender = 性别) %>% head(3) # 将性别列改为Gender,并将该列置于第一列
## # A tibble: 3 x 6
##   Gender 班级  姓名    语文  数学  英语
##   <chr>  <chr> <chr>  <dbl> <dbl> <dbl>
## 1 女     六1班 何娜      87    92    79
## 2 女     六1班 黄才菊    95    77    75
## 3 女     六1班 陈芳妹    79    87    66

4.3 保存

# 保留三科目平均成绩到新文档
df.out <- df %>% 
  rowwise() %>%
  mutate(平均值 = mean(c(语文, 数学, 英语))) %>%
  mutate(平均值 = round(平均值, 2)) # 保留两位有效位数

# write.csv(df.out, '六1-5班学生成绩平均值.csv', row.names= F, quote = F, fileEncoding = "UTF-8") # 存为csv
# writexl::write_xlsx(df.out, '六1-5班学生成绩平均值.xlsx') # 存为xlsx