r dataframe删除几列_R语言入门推荐:玩转数据处理120题(R语言tidyverse版本)

本文作者:张敬信
玩转数据处理120题之P1-P20(R语言tidyverse版本)
玩转数据处理120题之P21-P50(R语言tidyverse版本)
玩转数据处理120题之P51-P80(R语言tidyverse版本)
玩转数据处理120题之P81-P100(R语言tidyverse版本)
玩转数据处理120题之P101-P120(R语言tidyverse版本)

关于代码学习:不要复制粘贴,一个一个敲出来

一直都在想怎么开启R的更新,很多人都觉得R就是用来画图,其实不然,R做数据分析也是一个很不错的工具。生信中大量需要做数据分析,因此在进行R语言绘图前,有必要推荐数据处理120题,把dirty data 变成 clean data。这也是耗时最长的部分,考验耐心的时候到了。数据分析流程如下图。(生物数据分析也是如此)

b3450c49701795e3f0e33a850efcfe70.png

本文非常适合初学者,是张老师根据刘早起老师的panda版本更改而来,我自己也把这120个题目敲下来,又有一些感悟。感谢张老师,也感谢原作者早起python:刘早起。

题目1(创建数据框):创建DataFrame

代码及运行结果:

### 方法1
df <- data.frame(
  "grammer" = c("Python","C","Java","GO",NA,"SQL","PHP","Python"),
  "score" = c(1,2,NA,4,5,6,7,10)
)
df

### 方法2
library(tibble)
df <- tibble(
  "grammer" = c("Python","C","Java","GO",NA,"SQL","PHP","Python"),
  "score" = c(1,2,NA,4,5,6,7,10)
)

4ad09130afb6bec3d8195c04bbc57ec9.png
问题2(筛选行):提取含字符串"Python"的行

代码及运行结果

df %>%
  filter(grammer == "Python")

a3a42dee299d0ec29cf435dbc21ac878.png
题目3(查看列名):输出df的所有列名

代码及运行结果

names(df)

25296c9ac6e9ee0bab7dc333cb11fe5e.png
题目4(改列名):改第2列列名为popularity

代码及运行结果

df = df %>%
  rename(popularity = score)
df

ba6ea2e385d1ef821b3ebbc9494cf18b.png
题目5(统计频数):统计grammer列中每种编程语言出现的次数

代码及运行结果

df %>%
  count(grammer)   # 或者用 table(df$grammer)

bde48f1ff0b2138e4d83cedf1e690910.png
题目6(缺失值处理):将空值用上下值的平均值填充

代码及运行结果

df = df %>%
  mutate(popularity = zoo::na.approx(popularity))
df

fe56afe24c04609edc4fe58c220778dc.png

:dplyr包提供了fill()函数,可以用前值或后值插补缺失值。

题目7(筛选行):提取popularity列中值大于3的行

代码及运行结果

df %>%
  filter(popularity > 3)

a559b51a9d297b55ab01be7de0a321d7.png
题目8(数据去重):按grammer列进行去重

代码及运行结果

df %>%
  distinct(grammer, .keep_all = TRUE)

869fc92aead5f802328c13ed413daf4e.png
题目9(数据计算):计算popularity列平均值

代码及运行结果

df %>%
  summarise(popularity_avg = mean(popularity))

70f189a5863131e5ae211e4431237c37.png
题目10(格式转换):将grammer列转换为序列

代码及运行结果

df$grammer

29aeca5d1a100e86d3ddfc6d41d3c6e5.png

注:R从数据框中提取出来就是字符向量。

题目11(数据保存):将数据框保存为Excel

代码及运行结果:

writexl::write_xlsx(df, "filename.xlsx")
题目12(数据查看):查看数据的行数列数

代码及运行结果:

dim(df)

57ab5704dbe654c30c2e138c6cc49519.png
题目13(筛选行):提取popularity列值大于3小于7的行

代码及运行结果:

df %>%
  filter(popularity > 3 & popularity < 7)

c01856f24548ae10c09a449315127aab.png
题目14(调整列位置):交互两列的位置

代码及运行结果:

df %>%
  select(popularity, grammer)

baef52f04c57d9ad3316f3422e3120f8.png

:可配合everything()放置“其余列”,更强大的调整列位置的函数是dplyr1.0将提供的relacate().

题目15(筛选行):提取popularity列最大值所在的行

代码及运行结果:

df %>%
  filter(popularity == max(popularity))
# 或者用df %>% top_n(1, popularity)

420a0c776a23efc8987d8080a00e1e16.png
题目16(查看数据):查看最后几行数据

代码及运行结果:

tail(df)   # 默认是最后6行

:此外,head()查看前几行,dplyr包还提供了sample_n()和sample_frac()随机查看n行或某比例的行。

30be79419af29abb97248baf46403d7f.png
题目17(修改数据):删除最后一行数据

代码及运行结果:

df %>%
  slice(-n())

8d2bec2561779de149f7bff65352dc5a.png
题目18(修改数据):添加一行数据:"Perl", 6

代码及运行结果:

newrow = tibble(grammer="Perl", popularity=6)
 
df %>%
  bind_rows(newrow)

ee3eff3dfb7946c47dcb7cd8b7e0867c.png
题目19(数据整理):对数据按popularity列值从到大到小排序

代码及运行结果:

df %>%
  arrange(desc(popularity))

7e2855eab1536bdc88025a7d655e5e14.png

:不套一层desc(), 是默认从小到大排序。

题目20(字符统计):统计grammer列每个字符串的长度

代码及运行结果:

df %>%
  mutate(strlen = str_length(grammer))

df23a492a35c5b86cff0624e12aeef57.png
题目21(读取数据):读取本地Excel数据

代码及运行结果:

df = readxl::read_xlsx("21-50数据.xlsx")
df

df913c05fa4012681c3deb97f2f881f3.png
题目22(查看数据):查看df数据的前几行

代码及运行结果:

head(df)

ad581661aa4dee56b6980a1b768381f9.png

:此外,tail()查看后几行,dplyr包还提供了sample_n()和sample_frac()随机查看n行或某比例的行。

题目23(数据计算):将salary列数据转换为最大值与最小值的平均值

代码及运行结果:

df = df %>%
  separate(salary, into = c("low", "high"), sep = "-") %>%    # sep="-"也可以省略
  mutate(salary = (parse_number(low) + parse_number(high)) * 1000 / 2) %>%
  select(-c(low, high))
df

46b566e3c6383fcbf60ed313059a9c1e.png

或者来个高级的,用正则表达式提取数字,定义做计算的函数,再purrr::map_dbl做循环计算:

calc = function(x) sum(as.numeric(unlist(x))) * 1000 / 2
 
df %>%
  mutate(salary = map_dbl(str_extract_all(salary, "d+"), calc))   # 结果同上
题目24(分组汇总):根据学历分组,并计算平均薪资

代码及运行结果:

df %>% 
  group_by(education) %>% 
  summarise(salary_avg = mean(salary))

361e64c2af6f380a0f2f3fe43612cbbc.png
题目25(时间转换):将createTime列转换为"月-日"

代码及运行结果:

library(lubridate)
 
df %>% 
  mutate(createTime = str_c(month(createTime), "-", day(createTime)))

b0c74516e41c4d56fbf1d84e1b0cef7a.png
题目26(查看数据):查看数据结构信息

代码及运行结果:

df %>% 
  glimpse()    # 或者用str()

08793b80db8dfab18b0754a48bd419a7.png

object.size(df) # 查看对象占用内存

f26d290c863a4ed7a0d9ba44b2c08d0a.png
题目27(查看数据):查看数据汇总信息

代码及运行结果:

summary(df)

ff7fce4ca49dcf0b6958f18bbb5ee9a7.png
题目28(修改列):新增一列将salary离散化为三水平值

代码及运行结果:

df = df %>%
  mutate(class = case_when(
    salary >= 0 & salary < 5000      ~ "低",
    salary >= 5000 & salary < 20000 ~ "中",
TRUE                                ~ "高"))      # TRUE效果是其它
df

4d195cee2fe8809c851551dc250a8d20.png

或者用cut()函数:

df %>% 
  mutate(class = cut(salary, 
                     breaks = c(0,5000,20000,Inf), 
                     labels = c("低", "中", "高")))

:也可以用sjmisc包中的rec(),和SPSS的重新编码一样强大。

题目29(数据整理):按salary列对数据降序排列

代码及运行结果:

df %>% 
  arrange(desc(salary))

b34f75c5ac2ed4f6e06fdd1d551461bb.png
题目30(筛选行):提取第33行数据

代码及运行结果:

df[33,]

a8b2ec79fe2b7f64027ec38bc4ddd083.png

或者用

df %>% 
  slice(33)
题目31(数据计算):计算salary列的中位数

代码及运行结果:

median(df$salary)

55b8c043ce8ca3aa12d1dc4ee5ae7c3b.png

或者用

df %>% 
  summarise(salary_med = median(salary))

aa4b6e56dc31be27abbec9bba40ca0ae.png
题目32(数据可视化):绘制salary的频率分布直方图

代码及运行结果:

df %>%
  ggplot(aes(x = salary)) +
  geom_histogram(bins = 10)

5ad594963c0281cf55b8eb98520c13c2.png
题目33(数据可视化):绘制salary的频率密度曲线图

代码及运行结果:

df %>%
  ggplot(aes(x = salary)) +
  geom_density()

1698818452b824c4e36ef36f3b685451.png
题目34(数据删除):删除最后一列class

代码及运行结果:

df %>% 
  select(-class)

0be6ec4412a2fd4962aa26d84cb30460.png
题目35(数据操作):将df的第1列与第2列合并为新的一列

代码及运行结果:

df %>% 
  unite("newcol", 1:2, sep = " ")

4e82e1247b38c4addeb68227e1a153fc.png
题目36(数据操作):将education列与第salary列合并为新的一列

代码及运行结果:

df %>% 
  unite("newcol", c(education, salary), sep = " ")

7b0d5fb77d460d9e451bf7c5646c7005.png
题目37(数据计算):计算salary最大值与最小值之差

代码及运行结果:

max(df$salary) - min(df$salary)

bd2990858d36e6c0b4e7fd95e3569b9b.png

或者用

df %>% 
  summarise(range = max(salary) - min(salary))

d46e9b106d39ce889b8d2f19b9071bc2.png
题目38(数据操作):将第一行与最后一行拼接

代码及运行结果:

bind_rows(df[1,], df[nrow(df),])

99d4f2e5e1de25d9d0eebf70d8d61965.png
题目39(数据操作):将第8行添加到末尾

代码及运行结果:

bind_rows(df, df[8,]) %>% 
  tail()

14a7d01ebb3bf7fbf647c5ee08098f02.png
题目40(查看数据):查看每一列的数据类型

代码及运行结果:

df %>% 
  glimpse()     # 或者用str()

52ecd2fe9d7a2ce737a00001f4e8db91.png
题目41(数据操作):将createTime列设置为行索引

代码及运行结果:

df %>% 
  distinct(createTime, .keep_all = TRUE) %>% 
  column_to_rownames("createTime")

ecf917153a96ed0e58bdf033478ab07a.png

:行索引不允许有重复,所以先做了一步去重。

题目42(数据创建):生成一个和df长度相同的随机数数据框

代码及运行结果:

df1 = tibble(rnums = sample.int(10, nrow(df), replace = TRUE))
df1

316d1001a430e5facc1379a43bc37df3.png
题目43(数据连接):将上面生成的数据框与df按列合并

代码及运行结果:

df = bind_cols(df, df1)
df

65686c04484d19189e59b3d3f9bbfd97.png
题目44(修改列):生成新列new为salary列减去随机数列

代码及运行结果:

df = df %>% 
  mutate(new = salary - rnums)
df

6e808bf5169483a306b545912aed2595.png
题目45(检查缺失值):检查数据中是否含有任何缺失值

代码及运行结果:

anyNA(df)

1caac367182c53ac25bb07ff6af708e0.png
anyNA(df$salary)

1caac367182c53ac25bb07ff6af708e0.png

:naniar包提供了更强大的探索缺失值及缺失模式的函数,其中miss_var_summary()和miss_case_summary()可检查各列和各行缺失情况。

题目46(类型转换):将salary列的类型转换为浮点数

代码及运行结果:

df %>% 
  mutate(rnums = as.double(rnums))

ce2f1ebe06a71bc5f3d60e580d790257.png
题目47(数据汇总):计算salary列大于10000的次数

代码及运行结果:

df %>% 
  summarise(n = sum(salary > 10000))

d41e45871427fcf307b8d5fe2ce92e26.png

或者用

df %>% 
  count(salary > 10000)

3a8127efbb733a14f57151040d9de2a8.png
题目48(统计频数):查看每种学历出现的次数

代码及运行结果:

df %>% 
  count(education)

9bd1ca383adee41ee71990311215827b.png

或者用

table(df$education)

47015193f90892268564e1ec8afe3675.png
题目49(数据汇总):查看education列共有几种学历

代码及运行结果:

df %>% 
  distinct(education)

66d54615e8273f37ec6d36ec6b4185b9.png
题目50(筛选行):提取salary与new列之和大于60000的最后3行

代码及运行结果:

df %>% 
  filter(salary + new > 60000) %>% 
  slice((n()-2):n())

13f2157b903a6d2d8d78d04c9a0ada00.png
题目51(读取数据):使用绝对路径读取本地Excel数据

代码及运行结果:

df = readxl::read_xls("E:/R语言/R语言学习系列/R数据操作/codes/120problams/51-80数据.xls")
df

67634aae397701c962999d4e12ee5055.png
题目52(查看数据):查看数据框的前3行

代码及运行结果:

df %>% 
  head(3)

c941d03bb26c03d7ced7cbe30fd8bb9f.png
题目53(查看缺失值):查看每列数据缺失值情况

代码及运行结果:

library(naniar)
 
df %>% 
  miss_var_summary()

ec1d7e30043c4b1da67a6bc4fba6e5a0.png
题目54(查看缺失值):查看日期列含有缺失值的行

代码及运行结果:

df %>% 
  filter(is.na(日期))

453283c646abbfe276056eb81c73a298.png
which(is.na(df$日期))   # 日期列缺失的行号

abd717f2bc55720abdaf62f7f993b44a.png
题目55(查看缺失值):查看每列缺失值在哪些行

代码及运行结果:

naIdx = df %>%
  where_na()         # 返回NA的行列索引, 需要naniar包
 
split(naIdx[,1], naIdx[,2])

67c0196c0f1a9dadd7f7e762da2a8967.png
题目56(缺失值处理):删除所有存在缺失值的行

代码及运行结果:

df %>% 
  drop_na()

06bc1f767f4405fade158f5b427bd584.png

:若要删除某些列包含缺失值的行,提供列名即可。

题目57(数据可视化):绘制收盘价的折线图

代码及运行结果:

df %>% 
  ggplot(aes(日期, `收盘价(元)`)) +
  geom_line()

a9c29ca663a460d18f450b6eedc30bc8.png
题目58(数据可视化):同时绘制开盘价与收盘价

代码及运行结果:

df %>%
  select(日期, `开盘价(元)`, `收盘价(元)`) %>% 
  pivot_longer(-日期, 
               names_to = "type",
               values_to = "price") %>%
  ggplot(aes(日期, price, color = type)) +
  geom_line()

ccd198c8f36a9e08ee99f4a313873067.png

:为了自动添加图例,先对数据做了宽变长转换。

题目59(数据可视化):绘制涨跌幅的直方图

代码及运行结果:

df %>% 
  ggplot(aes(`涨跌幅(%)`)) +
  geom_histogram()

40cd3531f04e2cd375ab0e9e59191743.png
题目60(数据可视化):让直方图更细致

代码及运行结果:

df %>% 
  ggplot(aes(`涨跌幅(%)`)) +
  geom_histogram(bins = 40)

033b06e179b68af54b9a3c0f53302d47.png
题目61(数据创建):用df的列名创建数据框

代码及运行结果:

as_tibble(names(df))

e56bed20e7a8399e5baef4f68cacd1df.png
题目62(异常值处理):输出所有换手率不是数字的行

代码及运行结果:

df %>% 
  mutate(`换手率(%)` = parse_number(`换手率(%)`)) %>% 
  filter(is.na(`换手率(%)`))

c85007203290f8ddc6ac682a8522f73d.png
题目63(异常值处理):输出所有换手率为--的行

代码及运行结果:

df %>% 
  filter(`换手率(%)` == "--")

581f847ded763787b553fdec33069a8a.png
题目64(数据操作):重置df的行号

代码及运行结果:

rownames(df) = NULL    # R中无行号就是数字索引
题目65(异常值处理):删除所有换手率为非数字的行

代码及运行结果:

df %>% 
  mutate(`换手率(%)` = parse_number(`换手率(%)`)) %>% 
  filter(!is.na(`换手率(%)`))

e81e6a6721a8082dcd3acb65632fd9fa.png

补充:为了便于后续处理,做批量数值型转化, 并转化为tsibble对象

library(tsibble)
 
df = df %>% 
  mutate_at(vars(4:18), as.numeric) %>% 
  mutate(日期 = lubridate::as_date(日期)) %>%
  as_tsibble(index = 日期, key = c(代码, 简称))
df

368bcec3cb6b519bb584d4c13f60b91f.png
题目66(数据可视化):绘制换手率的密度曲线

代码及运行结果:

df %>%
  ggplot(aes(`换手率(%)`)) +
  geom_density()

e5023b6ad2a9e37447881900d17ad101.png
题目67(数据计算):计算前一天与后一天收盘价的差值

代码及运行结果:

df %>% 
  mutate(delta = `收盘价(元)` - lag(`收盘价(元)`)) %>% 
  select(日期, `收盘价(元)`, delta)

76119c4bebab1791b53dc7bfce69b59b.png
题目68(数据计算):计算前一天与后一天收盘价的变化率

代码及运行结果:

df %>% 
  mutate(change = (`收盘价(元)` - lag(`收盘价(元)`)) / `收盘价(元)`) %>% 
  select(日期, `收盘价(元)`, change)

977f662dbcc7ad145a772991a567d3da.png
题目69(数据操作):设置日期为行索引

代码及运行结果:

df %>% 
  column_to_rownames("日期")

101f43e4ed799a4a8a93bfc746a8306e.png
题目70(数据计算):对收盘价做步长为5的滑动平均

代码及运行结果:

df %>%
  mutate(avg_5 = slide_dbl(`收盘价(元)`, mean, na.rm = TRUE, 
                           .size = 5, .align = "center")) %>% 
  select(日期, `收盘价(元)`, avg_5)

b304efba7e257fcba6391ead81f69618.png
题目71(数据计算):对收盘价做步长为5的滑动求和

代码及运行结果:

df %>%
  mutate(sum_5 = slide_dbl(`收盘价(元)`, sum, na.rm = TRUE, 
                           .size = 5, .align = "center-left")) %>% 
  select(日期, `收盘价(元)`, sum_5)

feb1207fea1fce99a430038c0630cc01.png
题目72(数据可视化):将收盘价及其5日均线、20日均线绘制在同一个图上

代码及运行结果:

df %>%
  mutate(avg_5 = slide_dbl(`收盘价(元)`, mean, na.rm = TRUE, .size = 5,
                            .align = "center"),
         avg_20 = slide_dbl(`收盘价(元)`, mean, na.rm = TRUE, .size = 20, 
                            .align = "center-left")) %>% 
  pivot_longer(c(`收盘价(元)`, avg_5, avg_20),
                  names_to = "type",
                  values_to = "price") %>% 
  ggplot(aes(日期, price, color = type)) +
    geom_line()

8e2d9b54c94bd7c416c209e503fdeac4.png
题目73(数据重采样):按周为采样规则,计算一周收盘价最大值

代码及运行结果:

weekmax = df %>% 
  index_by(weeks = ~ yearweek(.)) %>%    #周度汇总
  summarise(max_week = max(`收盘价(元)`, na.rm = TRUE))
weekmax

65d04954b753d0363ae8409d7ef37ff4.png
题目74(数据可视化):绘制重采样数据与原始数据

代码及运行结果:

ggplot() +
  geom_line(data = df, aes(日期, `收盘价(元)`), color = "steelblue") +
  geom_line(data = weekmax, aes(weeks, max_week), color = "red")

51dfaf0708b4e7aa1eb8165525a125d7.png
题目75(数据操作):将数据往后移动5天

代码及运行结果:

bind_cols(df[,1:3], map_dfc(df[,-(1:3)], lag, n = 5))

40349b38845f2c1bc166b35ad6b6e24d.png

:这是批量做后移,单个变量做后移用mutate(var = lag(var, 5)即可。

题目76(数据操作):将数据往前移动5天

代码及运行结果:

bind_cols(df[,1:3], map_dfc(df[,-(1:3)], lead, n = 5))

36e0a6ca9be21a26919a810022a52e85.png
题目77(数据操作):计算开盘价的累积平均

代码及运行结果:

rlt = df %>% 
  mutate(累积平均 = cummean(`开盘价(元)`)) %>% 
  select(日期, `开盘价(元)`, 累积平均)
rlt

33174b7709448b60d94f524b2c3ee9a1.png
题目78(数据计算):绘制开盘价的累积平均与原始数据的折线图

代码及运行结果:

rlt %>% 
  pivot_longer(-日期, names_to = "type", values_to = "price") %>% 
  ggplot(aes(日期, price, color = type)) +
    geom_line()

7f2a0a2b0a74cc3831e7c7a0be71e576.png
题目79(数据计算):计算布林指标

代码及运行结果:

boll = df %>%
  mutate(avg_20 = slide_dbl(`收盘价(元)`, mean, na.rm = TRUE, .size = 20, 
                            .align = "center-left"), 
         sd_20 = slide_dbl(`收盘价(元)`, sd, na.rm = TRUE, .size = 20, 
                           .align = "center-left"),
         up = avg_20 + 2 * sd_20,
         down = avg_20 - 2 * sd_20) %>% 
  select(日期, `收盘价(元)`, avg_20, up, down)

 boll %>% sample_n(10)

5295f3faf34a2b25d22b029efd65c162.png
题目80(数据可视化):绘制布林曲线

代码及运行结果:

boll %>% 
  pivot_longer(-日期, names_to = "type", values_to = "price") %>% 
  ggplot(aes(日期, price, color = type)) + 
    geom_line()

fdeb70c47dc59629b934537aa1c98419.png
题目81(加载查看包):加载并查看tidyverse包版本

代码及运行结果:

library(tidyverse)

d38d5fed7353c8cc3f82325c28e5d7b9.png
题目82(生成随机数):生成20个0~100的随机数,创建数据框

代码及运行结果:

set.seed(123)                # 保证结果出现
df1 = tibble(nums = sample.int(100, 20))
df1

b9bd0931e726dfb03dd4b521296696a2.png
题目83(生成等差数):生成20个0~100固定步长的数,创建数据框

代码及运行结果:

df2 = tibble(nums = seq(0, 99, by = 5))
df2

876173353384b73d803626b48ff7819a.png
题目84(生成指定分布随机数):生成20个标准正态分布的随机数,创建数据框

代码及运行结果:

set.seed(111)
df3 = tibble(nums = rnorm(20, 0, 1))
df3

5a941898e762fbdec38adea445178fa0.png
题目85(合并数据):将df1, df2, df3按行合并为新数据框

代码及运行结果:

bind_rows(df1, df2, df3)

c9dc2001317270303dc07ee9547fba39.png
题目86(合并数据):将df1, df2, df3按列合并为新数据框

代码及运行结果:

df = bind_cols(df1, df2, df3)
df

596a9b7823afb6a66d80da08bef4d66a.png
题目87(查看数据):查看df所有数据的最小值、25%分位数、中位数、75%分位数、最大值

代码及运行结果:

unlist(df) %>% 
  summary()

9acb3830d0174aa65b67646ae58830ea.png
题目88(修改列名):修改列名为col1, col2, col3

代码及运行结果:

df = df %>% 
  set_names(str_c("col", 1:3))
df

d3c0615afa6c55983e1d4891ed568850.png

:若只修改个别列名,用rename(newname=oldname).

题目89(数据操作):提取在第1列中而不在第2列中的数

代码及运行结果:

setdiff(df$col1, df$col2)

f9e060c3e4ff35cca6b936474f240040.png
题目90(数据操作):提取在第1列和第2列出现频率最高的三个数字

代码及运行结果:

tibble(nums = c(df$col1, df$col2)) %>% 
  group_by(nums) %>% 
  summarise(frq = n()) %>% 
  arrange(desc(frq)) %>% 
  slice(1:3)

673d0f1791e9fecee21f9bf5475ceaea.png

或者用

c(df$col1, df$col2) %>% 
  table() %>% 
  sort(decreasing = TRUE) %>% 
  .[1:3]

88f05138d8ab9f19beb8696ab165fed5.png

或者用

rlt = tibble(nums = c(df$col1, df$col2)) %>%
  sjmisc::frq(nums, sort.frq = "desc") 
 
rlt[[1]][1:3,]

8849d3465d9a61df206c1328e1512de5.png
题目91(数据操作):提取第1列可以整除5的数的位置

代码及运行结果:

which(df$col1 %% 5 == 0)

dfdff84d40226e2d583ebe26da8afa7b.png
题目92(数据计算):计算第1列的1阶差分

代码及运行结果:

df %>% 
  mutate(diff1 = col1 - lag(col1))

3667d038e3fdee259b8c8525de1efbcb.png

注:若只是要数值,用diff(df$col1)即可。

题目93(数据操作):将col1, col2, col3三列顺序颠倒

代码及运行结果:

df %>% 
  select(rev(names(df)))

905ea51bbddb96cd032c696e7ddde329.png

:更灵活的调整列序,dplyr1.0将提供relocate()函数。

题目94(数据操作):提取第一列位置在1,10,15的数

代码及运行结果:

df[c(1,10,15),1]

5f77ad5d5dbda98f58ac6644d8d9a4ac.png

或者用

df %>% 
  select(col1) %>% 
  slice(1,10,15)
题目95(数据操作):查找第一列的局部最大值位置

代码及运行结果:

rlt = df %>% 
  mutate(diff = sign(col1 - lag(col1)) + sign(col1 - lead(col1))) 
 
which(rlt$diff == 2)

510b0abeac52631a2365acafe97008bd.png
题目96(数据计算):按行计算df每一行的均值

代码及运行结果:

rowMeans(df)    # 或者 apply(df, 1, mean)

5c2efd232f275fa703d26a1c48e8fc38.png
题目97(数据计算):对第二列计算步长为3的移动平均值

代码及运行结果:

df %>%
  mutate(avg_3 = tsibble::slide_dbl(col2, mean, .size = 3, .align = "center"))

87b4955595c5f20824f82c4dadaf7de7.png
题目98(数据计算):按第三列值的大小升序排列

代码及运行结果:

df %>% 
  arrange(col3)

194e455f46628f6ddc0398d99abed985.png
题目99(数据操作):按第一列大于50的数修改为"高"

代码及运行结果:

df %>% 
  mutate(col1 = sjmisc::rec(col1, rec = "50:max=高; else=copy"))
# 或者用 df[df$col1 > 50, 1] = "高"

2157fc0aade331bd0dfe4357579519f4.png

注:这里采用更有实用价值的重新编码。

题目100(数据计算):计算第一列与第二列的欧氏距离

代码及运行结果:

dist(t(df[,1:2]))

aac8782de4f0cf1d1076468e53f9162b.png
题目101(数据读取):从csv文件中读取指定数据:读取前10行, positionName和salary列

代码及运行结果:

read.csv("数据1_101-120涉及.csv", nrows = 10) %>% 
  select(positionName, salary)

61cff707034b86d4c299717a4926ee28.png

注1:该数据是GBK编码,为避免中文乱码,GBK编码的csv或txt用read.csv()读取;UTF-8编码的csv或txt用readr::read_csv()读取;若用read_csv()读取GBK编码文件,需要设置编码(见题目110)。

注2:R中常规读取数据不能在读取时选择列,采用读取之后选择列。

题目102(数据读取):从csv文件中读取数据,将薪资大于10000的改为"高"

代码及运行结果:

df = read_csv("数据2_101-120涉及.csv") %>% 
  mutate(薪资水平 = if_else(薪资水平 > 10000, "高", "低"))

8595355b67c6958b9ab9e5cba2aeb06f.png
题目103(数据操作):从df中对薪资水平每隔20行进行抽样

代码及运行结果:

df %>% 
  slice(seq(1, n(), by = 20))  
# 或者用df[seq(1, nrow(df), 20),]

d5adaf4eee9499b9523e3c7726bd3cfc.png
题目104(数据操作):取消使用科学记数法

代码及运行结果:

set.seed(123)
df = tibble(data = runif(10) ^ 10) %>% 
  round(3)
df

28149d5d4197fde38b29c2b2e8d0a38c.png
题目105(数据操作):将上一题的数据转换为百分数

代码及运行结果:

df %>% 
  mutate(val = scales::percent(val, 0.01))

5a4bfa241cf4e4b7f1207d137851e993.png
题目106(数据操作):查找上一题数据中第3大值的行号

代码及运行结果:

order(df$val, decreasing = TRUE)[3]

d9c875d9f006aa466670ac2cf4c07406.png
题目107(数据操作):反转df的行

代码及运行结果:

df %>% 
  slice(rev(1:n()))
# 或者 df[rev(1:nrow(df)),]

c83734d3daf6eadc4e93ca295fc9baa4.png
题目108(数据连接:全连接):根据多列匹配合并数据,保留df1和df2的观测

代码及运行结果:

df1 <- tibble(
  key1 = c("K0","K0","K1","K2"),
  key2 = c("K0","K1","K0","K1"),
  A = str_c('A', 0:3),
  B = str_c('B', 0:3)
)
 
df2 <- tibble(
  key1 = c("K0","K1","K1","K2"),
  key2 = str_c("K", rep(0,4)),
  C = str_c('C', 0:3),
  D = str_c('D', 0:3)
)
 
df1

e629464caba2f0245bf36912cfff978d.png
df2

70b6935e96798ca7e6f434ccef2264da.png
df1 %>% 
  full_join(df2, by = c("key1", "key2"))

cc98c2497afb3ec9ab80665757c98b00.png
题目109(数据连接:左连接):根据多列匹配合并数据,只保留df1的观测

代码及运行结果:

df1 %>% 
  left_join(df2, by = c("key1", "key2"))

40aa017ada98525bbe9f7a182a55e0ee.png

注:dplyr包还提供了右连接:right_join(),内连接:inner_join(),以及用于过滤的连接:半连接:semi_join(),反连接:anti_join().

题目110(数据处理):再次读取数据1并显示所有列

代码及运行结果:

df <- read_csv("数据1_101-120涉及.csv", 
               locale = locale(encoding = "GBK")) %>%
      glimpse()

19815368a6630e73211156c46d19e40e.png

4e07b281548dde11b133bf7071382d6b.png

8674f4c74789d49dffe3d12d03f9b187.png
题目111(数据操作):查找secondType与thirdType值相等的行号

代码及运行结果:

which(df$secondType == df$thirdType)

0ed752f54c1d3cfa1385e2399b129777.png
题目112(数据操作):查找薪资大于平均薪资的第三个数据

代码及运行结果:

df %>% 
  filter(salary > mean(salary)) %>% 
  slice(3)

1a768be4c5655fae48392d000da1b2dc.png
题目113(数据操作):将上一题数据的salary列开根号

代码及运行结果:

df %>% 
  mutate(salary_sqrt = sqrt(salary)) %>% 
  select(salary, salary_sqrt)

47a0759c1f039d095501e819b502c9b1.png
题目114(数据操作):将上一题数据的linestation列按_拆分

代码及运行结果:

df %>% 
  separate(linestaion, into = c("line", "station"), sep = "_", remove = FALSE) %>% 
  select(linestaion, line, station)

48a0396d4bd97c2d929619e225204f2c.png

:正常需要先按“;”分割,再分别按“-”分割。

题目115(数据查看):查看上一题数据一共有多少列

代码及运行结果:

ncol(df)

5e759f89c1fb423df5baab076238d688.png
题目116(数据操作):提取industryField列以"数据"开头的行

代码及运行结果:

df %>% 
  filter(str_detect(industryField, "^数据"))

b868ae01d5306f6fbcc27346bcdaee4c.png
题目117(数据分组汇总):以salary score和positionID做数据透视表

代码及运行结果:

df %>% 
  group_by(positionId) %>% 
  summarise(salary_avg = mean(salary),
            score_avg = mean(score))

65f683446d7aedb68977b57541d933d5.png
题目118(数据分组汇总):同时对salary、score两列进行汇总计算

代码及运行结果:

df %>% 
  summarise_at(vars(salary, score), list(~sum(.), ~mean(.), ~min(.)))

eef92bd9546b64ce849bf12ffb48d3ff.png

:若要分组再这样汇总,前面加上group_by(grpvar)即可;若改用dplyr1.0的cross()会更加简洁。

题目119(数据分组汇总):同时对不同列进行不同的汇总计算:对salary求平均,对score求和

代码及运行结果:

df %>% 
  summarise(salary_avg = mean(salary),
            score_sum = sum(score))

f2b8c588056e81a9e47f78b1317d8734.png

:若要分组再这样汇总,前面加上group_by(grpvar)即可。

题目120(数据分组汇总):计算并提取平均薪资最高的区

代码及运行结果:

df %>% 
  group_by(district) %>% 
  summarise(salary_avg = mean(salary)) %>% 
  top_n(1, salary_avg)

464e3eae3b788f5d9f6b5103ca494f77.png

虽然题目不是很难,但是涉及的面还是比较广的,在进行R语言绘图前(文中介绍了部分数据可视化的内容,但对于科研绘图来讲还有很多不足),充分了解R的数据处理操作十分必要,数据分析大量的时间是在数据预处理的工作上,这部分内容的技巧性较强,还需要多多理解,多总结经验,再次感谢作者整理~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值