tidyverse
group_by 分组统计
gather()和spread()
简单地说,gather()是列转行,而spread()是行转列。
请看下面的示例:
> df
id class grade
1 1 a 81
2 2 b 82
3 3 a 83
4 4 b 84
5 5 a 85
6 6 b 86
7 7 a 87
8 8 b 88
9 9 a 89
10 10 b 90
*可以使用spread()将class中的某个字段的取值拆分成多个列。
> df_2 = df %>% spread(key = 'class', value = 'grade')
> df_2
id a b
1 1 81 82
2 2 83 84
3 3 85 86
4 4 87 88
5 5 89 90
*也可以使用gather()将df_2中的a列和b列转换成某字段的值,就是把多列字段聚合在一起。
> df_2 %>% gather("a", "b", key = 'class', value = 'grade')
id class grade
1 1 a 81
2 2 a 83
3 3 a 85
4 4 a 87
5 5 a 89
6 1 b 82
7 2 b 84
8 3 b 86
9 4 b 88
10 5 b 90
unite()和separate()
这个一般用于字符串,也可以用于数字,就是把一列分成两列,或者把两列拼成一列。
unite()默认使用"_"来拼接,也可以用sep来指定符号。
> df_3 = df_2 %>% unite('ab', 'a', 'b', sep='*')
id ab
1 1 81*82
2 2 83*84
3 3 85*86
4 4 87*88
5 5 89*90
separate()中一般用非数字字符的符号作为分割符,也可以用sep指定分割符,支持正则。
> df_4 = df_3 %>% separate("ab", into=c("a", "b"))
id a b
1 1 81 82
2 2 83 84
3 3 85 86
4 4 87 88
5 5 89 90
注意,这里的数字都会被处理成字符串:
> str(df_4)
'data.frame': 5 obs. of 3 variables:
$ id: num 1 2 3 4 5
$ a : chr "81" "83" "85" "87" ...
$ b : chr "82" "84" "86" "88" ...
> str(df_2)
'data.frame': 5 obs. of 3 variables:
$ id: num 1 2 3 4 5
$ a : int 81 83 85 87 89
$ b : int 82 84 86 88 90
tibble
可以使用as_tibble把dataframe转换成tibble格式,也可以直接构造一个tibble。
如果你已经熟悉了data.frame(),请注意:tibble永远不会改变输入的类型(例如,它永远不会将字符串转换为因子!)
> a = tibble(a = c("yang", "y"), b = c(1,2))
> a
# A tibble: 2 x 2
a b
<chr> <dbl>
1 yang 1
2 y 2
#rep()中的each参数是让每个数重复多少次,times参数是整体重复多少次。
> tibble(a = rep(1:3, each = 3))
# A tibble: 9 x 1
a
<int>
1 1
2 1
3 1
4 2
5 2
6 2
7 3
8 3
9 3
在引用字段时,可以使用a$a 或者 a[['a']]。
> a[['a']]
[1] "yang" "y"
在管道符号中,要注意加个点,如'.$x' 或者'.[['a']]'。
> a %>% .[['a']]
[1] "yang" "y"
注意,这种表示方法在管道符中比较好用,因为可以用变量名代替字段名,这点很重要,以前不知道。
> x = 'a'
> a %>% .[[x]] #否则会把变量名直接当字段名,即认为字段为"x"
[1] "yang" "y"
连接
过滤连接 semi_join, anti_join
用于对数据进行筛选
> m
id value
1 1 2
2 2 3
3 3 4
> n
id value
1 0 2
2 2 3
3 3 5
#可以在向量中指定两边连接的字段,一个等号。
#对m表进行筛选,只保留匹配到的记录。
> m %>% semi_join(n, c("id" = "id"))
id value
1 2 3
2 3 4
#对m表进行筛选,只保留匹配不到的记录。
> m %>% anti_join(n, "id")
id value
1 1 2
常用连接
inner_join(x, y) merge(x, y)
left_join(x, y) merge(x, y, all.x = TRUE)
right_join(x, y) merge(x, y, all.y = TRUE),
full_join(x, y) merge(x, y, all.x = TRUE, all.y = TRUE)
dplyr中的连接速度比merge()快很多。
集合操作
针对表中每行记录进行操作。
intersect(x, y):仅返回在两表中共同的行。
union(x, y):返回两表记录的并集。
setdiff(x, y):返回存在于x表中,但不在y表中的记录。(semi_join只考虑某个字段)
> union(m,n)
id value
1 1 2
2 3 5
3 3 4
4 0 2
5 2 3
> intersect(m, n)
id value
1 2 3
> setdiff(m,n)
id value
1 1 2
2 3 4