R语言tibble的连接以及分组汇总操作


前言

这篇文章开始介绍一些对tibble数据的一些数据框之间的一些操作,其中包括数据框的直接连接,以特定观测的值进行连接,以及使用一个tibble数据集对另一个tibble的基于某一个观测的筛除,还有对数据的分组汇总的操作。


一、对数据框之间的一些操作

下面我将通过构建一些简单的tibble数据作为示范来介绍一下对tibble数据框之间的一些操作。创建两个数据框,一个为学生身高的数据框,一个为学生体重的数据框,这两个数据框是有交集但是不存在包含关系。

library(tidyverse)
library(dplyr)

#创建两个数据集,这两个数据集为身高体重的数据
h_table <-tibble(name = c("A","B","D"),sex = c(0,1,1),height = c(170,180,190))
w_table <- tibble(name = c("A","B","C"),sex = c(0,1,1),weight = c(50,65,70))
> h_table
# A tibble: 3 × 3
  name    sex height
  <chr> <dbl>  <dbl>
1 A         0    170
2 B         1    180
3 D         1    190
> w_table
# A tibble: 3 × 3
  name    sex weight
  <chr> <dbl>  <dbl>
1 A         0     50
2 B         1     65
3 C         1     70

1. 对两个数据框之间进行筛除

对两个数据框进行筛除的函数主要是anti_join函数,使用将通过参数对函数提供两个数据框,并且指定特定的变量,以第一个数据框和指定变量列为基准,剔除两个数据框存在交集的观测(将观测剔除的条件是指定变量存在交集),输出的是第一个数据框当中不是交集的观测。

h_table |>
  anti_join(w_table,by = "name")
  # 将身高表格当中,与体重表格姓名相同的学生剔除
  > h_table |>
+   anti_join(w_table,by = "name")
# A tibble: 1 × 3
  name    sex height
  <chr> <dbl>  <dbl>
1 D         1    190

下面以体重表格为基础再次执行anti_join函数。

w_table |>
  anti_join(h_table,by = "name")
  # 剔除体重表格中与身高表格中姓名相同的观测
  > w_table |>
+   anti_join(h_table,by = "name")
# A tibble: 1 × 3
  name    sex weight
  <chr> <dbl>  <dbl>
1 C         1     70

2.对两个数据框进行连接

主要使用的函数为inner_join函数,该函数也是将传递进去的两个数据框进行以指定变量相连接的操作,最后输出的是连接后的表格。

h_table |>
  inner_join(w_table,by = c("name","sex"))
  # A tibble: 2 × 4
  name    sex height weight
  <chr> <dbl>  <dbl>  <dbl>
1 A         0    170     50
2 B         1    180     65

这里输出的是两个表格中在姓名和性别同时具有交集的表格。如果我们在这里只指定一个变量,那么两个表格当中相同的变量将会被加上.x或者.y的后缀,来申明该同名的变量来自哪一个数据框。

h_table |>
  inner_join(w_table,by = c("name"))
  > h_table |>
+     inner_join(w_table,by = c("name"))
# A tibble: 2 × 5
  name  sex.x height sex.y weight
  <chr> <dbl>  <dbl> <dbl>  <dbl>
1 A         0    170     0     50
2 B         1    180     1     65

3. 直接连接

函数bind_rowsbind_cols可以实现对数据集的直接连接。

bind_cols(h_table,w_table)
bind_rows(h_table,w_table)
> bind_cols(h_table,w_table)
New names:
• `name` -> `name...1`
• `sex` -> `sex...2`
• `name` -> `name...4`
• `sex` -> `sex...5`
# A tibble: 3 × 6
  name...1 sex...2 height name...4 sex...5 weight
  <chr>      <dbl>  <dbl> <chr>      <dbl>  <dbl>
1 A              0    170 A              0     50
2 B              1    180 B              1     65
3 D              1    190 C              1     70
> bind_rows(h_table,w_table)
# A tibble: 6 × 4
  name    sex height weight
  <chr> <dbl>  <dbl>  <dbl>
1 A         0    170     NA
2 B         1    180     NA
3 D         1    190     NA
4 A         0     NA     50
5 B         1     NA     65
6 C         1     NA     70

在这两个函数下是直接将两个数据框连接,里面也有一些参数可以选择。

4.将两个表格的全部进行粘合

我们可以看到无论是anti_join还是inner_join我们都没有办法将两张表当中全部的信息表现在一个表内,这个时候要是只使用这两个函数将两个表缝合为一张表,并且确实的值由NA表示,在数据观测交少,两个表的区别不大的时候可以采用以下的方法。

  1. 首先使用inner_join函数将两个表已经存在的交集合并。
  2. 其次将合并的新表分别和使用anti_join函数排除的两张表连接(这个时候要使用mutate函数生成另外一个表没有的变量,并且使用NA填充)
  3. 使用bind_rows函数将两个表纵向连接。
df_1 <- h_table |>
  inner_join(w_table,by = c("name","sex"))#直接连接的表
 df_2 <- h_table |>
      anti_join(w_table,by = "name")|>
      mutate(weight = NA)
df_3 <- w_table |>
      anti_join(h_table,by = "name")|>
      mutate(height = NA)
 to_table <- df_1 |>#将三个表连接
 	bind_rows(df_2)|>
 	bind_rows(df_3)

这边在编写的时候也可以使用|>方法顺着思路下去

to_table <-h_table |>
  inner_join(w_table,by = c("name","sex")) |>
  bind_rows(
    h_table |>
      anti_join(w_table,by = "name")|>
      mutate(weight = NA)
  ) |>
  bind_rows(
    w_table |>
      anti_join(h_table,by = "name")|>
      mutate(height = NA)
  )
  to_table
# A tibble: 4 × 4
  name    sex height weight
  <chr> <dbl>  <dbl>  <dbl>
1 A         0    170     50
2 B         1    180     65
3 D         1    190     NA
4 C         1     NA     70

|>的熟练使用可以让我们的思路连贯起来。

6. 分组计算

在我们汇总得到总表之后我们也可以是使用group_by summarize函数进行分类汇总。

to_table |>
  group_by(sex) |>
  summarize(
    avg_height = mean(height,na.rm = T),
    avg_weight = mean(weight,na.rm = T)
  )
  # A tibble: 2 × 3
    sex avg_height avg_weight
  <dbl>      <dbl>      <dbl>
1     0        170       50  
2     1        185       67.5

7. 后续对数据的补充

假设现在我得到了一张学生班级和学科成绩的数据,我想要从这个表中提取出学生班级的信息并且匹配到我的汇总表当中,这个时候我们可以使用select将数据提取出来和distinct函数将信息唯一化,再使用inner_join函数进行匹配连接。(selectdistinc函数的使用方法可以参考我另外一篇文章tidyverse包对tibble数据框的基本操作

class_table <- tibble(
					  name = c("A","A","B","B","c","C","D","D"),
                      class = c("01","01","01","01","02","02","02","02"),
                      subject = c("E","M","E","M","E","M","E","M"),
                      score = c(100,99,50,80,70,80,70,100)
                      )
> class_table
# A tibble: 8 × 4
  name  class subject score
  <chr> <chr> <chr>   <dbl>
1 A     01    E         100
2 A     01    M          99
3 B     01    E          50
4 B     01    M          80
5 c     02    E          70
6 C     02    M          80
7 D     02    E          70
8 D     02    M         100

下面对该表的信息进行提取,再粘合。

to_table |>
  inner_join(
    class_table |>
      select(name,class)|>
      distinct(),
    by = "name"
  )
  # A tibble: 4 × 5
  name    sex height weight class
  <chr> <dbl>  <dbl>  <dbl> <chr>
1 A         0    170     50 01   
2 B         1    180     65 01   
3 D         1    190     NA 02   
4 C         1     NA     70 02 

这样我们就可以已身高体重表为基本往里面添加信息了。

总结

熟练地使用dplyr可以让我们在重构数据和补充数据上得心应手。在这个例子上我们也可以对成绩汇总,取均值,以性别为分组,或者以班级为分组,也可以使用pivor_long函数将class_table拉长。

  • 24
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值