首页 > > > tidyfst中的mutate族函数
作者:黄天元,复旦大学博士在读,热爱数据科学与开源工具(R),致力于利用数据科学迅速积累行业经验优势和科学知识发现,涉猎内容包括但不限于信息计量、机器学习、数据可视化、应用统计建模、知识图谱等,著有《R语言数据高效处理指南》(《R语言数据高效处理指南》(黄天元)【摘要 书评 试读】- 京东图书,《R语言数据高效处理指南》(黄天元)【简介_书评_在线阅读】 - 当当图书)。知乎专栏:R语言数据挖掘。邮箱:huang.tian-yuan@qq.com.欢迎合作交流。
为数据框构造一个新的列,也是非常常用的操作。在dplyr包中,我们常常用mutate来增添一个新的列。下面来介绍一下tidyfst中利用data.table所制成的mutate族函数,看看它们都是如何使用的。
这个函数与dplyr中保持一致,用法一模一样:
library(tidyfst)
#>
#> Life's short, use R.
# 增添一列名为one,内容全为1;同时,让所有的Sepal.Length列数值加1
iris %>% mutate_dt(one = 1,Sepal.Length = Sepal.Length + 1)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species one
#> <num> <num> <num> <num> <fctr> <num>
#> 1: 6.1 3.5 1.4 0.2 setosa 1
#> 2: 5.9 3.0 1.4 0.2 setosa 1
#> 3: 5.7 3.2 1.3 0.2 setosa 1
#> 4: 5.6 3.1 1.5 0.2 setosa 1
#> 5: 6.0 3.6 1.4 0.2 setosa 1
#> ---
#> 146: 7.7 3.0 5.2 2.3 virginica 1
#> 147: 7.3 2.5 5.0 1.9 virginica 1
#> 148: 7.5 3.0 5.2 2.0 virginica 1
#> 149: 7.2 3.4 5.4 2.3 virginica 1
#> 150: 6.9 3.0 5.1 1.8 virginica 1
如果只想要新增列,可以使用transmute_dt函数:
library(tidyfst)
#>
#> Life's short, use R.
iris %>% transmute_dt(one = 1,Sepal.Length = Sepal.Length + 1)
#> one Sepal.Length
#> <num> <num>
#> 1: 1 6.1
#> 2: 1 5.9
#> 3: 1 5.7
#> 4: 1 5.6
#> 5: 1 6.0
#> ---
#> 146: 1 7.7
#> 147: 1 7.3
#> 148: 1 7.5
#> 149: 1 7.2
#> 150: 1 6.9
原位更新的概念是data.table中一个重要的概念,从本质上,其实相当于做了更改之后,直接赋值给自己,但是这个过程是无法让人察觉到的。举个例子:
mutate_ref(a,one = 1,two = 2)
# 相当于
mutate_dt(a,one = 1,two = 2) -> a但是为什么要这么做呢?因为数据量比较大的时候,mutate_dt其实需要先对数据进行复制,在复制后的数据上面做更改。这样做有好处,那就是如果做错了,原始数据也不会发生变化,可以随时还原。但是它需要更多的内存,也需要更长的时间。因此,如果保证不需要回滚,使用原位的更新可以更加高效。下面我们来尝试实际例子:
# 把iris复制一份给a变量
copy(iris) -> a
# 原位更新
mutate_ref(a,one = 1,two = 2)
# 查看更新后的a
a
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species one two
#> <num> <num> <num> <num> <fctr> <num> <num>
#> 1: 5.1 3.5 1.4 0.2 setosa 1 2
#> 2: 4.9 3.0 1.4 0.2 setosa 1 2
#> 3: 4.7 3.2 1.3 0.2 setosa 1 2
#> 4: 4.6 3.1 1.5 0.2 setosa 1 2
#> 5: 5.0 3.6 1.4 0.2 setosa 1 2
#> ---
#> 146: 6.7 3.0 5.2 2.3 virginica 1 2
#> 147: 6.3 2.5 5.0 1.9 virginica 1 2
#> 148: 6.5 3.0 5.2 2.0 virginica 1 2
#> 149: 6.2 3.4 5.4 2.3 virginica 1 2
#> 150: 5.9 3.0 5.1 1.8 virginica 1 2
在扩增列的时候,有时候需要依据条件来赋值,这在dplyr中目前是做不到的。在以往的工作中,我也每每是在data.table中来做,因此在做tidyfst的时候,我直接把这个功能加了进来。现在我会举个例子,我现在想增加一列,在iris数据框中Petal.Width等于0.2的时候,赋值为1。我们进行一个演示:
# 只截取3-8行来演示
iris[3:8,] %>%
mutate_when(Petal.Width == .2, #当etal.Width等于0.2的时候
one = 1) #列名称为one的列赋值为1
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species one
#> <num> <num> <num> <num> <fctr> <num>
#> 1: 4.7 3.2 1.3 0.2 setosa 1
#> 2: 4.6 3.1 1.5 0.2 setosa 1
#> 3: 5.0 3.6 1.4 0.2 setosa 1
#> 4: 5.4 3.9 1.7 0.4 setosa NA
#> 5: 4.6 3.4 1.4 0.3 setosa NA
#> 6: 5.0 3.4 1.5 0.2 setosa 1
想要定制化地对指定列进行更新,有助于提高效率。举个例子,我们现在对iris中所有数值型的变量加1:
iris %>%
mutate_vars(is.numeric,function(x) x+1)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <num> <num> <num> <num> <fctr>
#> 1: 6.1 4.5 2.4 1.2 setosa
#> 2: 5.9 4.0 2.4 1.2 setosa
#> 3: 5.7 4.2 2.3 1.2 setosa
#> 4: 5.6 4.1 2.5 1.2 setosa
#> 5: 6.0 4.6 2.4 1.2 setosa
#> ---
#> 146: 7.7 4.0 6.2 3.3 virginica
#> 147: 7.3 3.5 6.0 2.9 virginica
#> 148: 7.5 4.0 6.2 3.0 virginica
#> 149: 7.2 4.4 6.4 3.3 virginica
#> 150: 6.9 4.0 6.1 2.8 virginica
对所有表头名称带“Se”的列加1:
iris %>%
mutate_vars("Se",function(x) x+1)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <num> <num> <num> <num> <fctr>
#> 1: 6.1 4.5 1.4 0.2 setosa
#> 2: 5.9 4.0 1.4 0.2 setosa
#> 3: 5.7 4.2 1.3 0.2 setosa
#> 4: 5.6 4.1 1.5 0.2 setosa
#> 5: 6.0 4.6 1.4 0.2 setosa
#> ---
#> 146: 7.7 4.0 5.2 2.3 virginica
#> 147: 7.3 3.5 5.0 1.9 virginica
#> 148: 7.5 4.0 5.2 2.0 virginica
#> 149: 7.2 4.4 5.4 2.3 virginica
#> 150: 6.9 4.0 5.1 1.8 virginica
把所有的列,转为字符型:
iris %>% mutate_vars(.func = as.character)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <char> <char> <char> <char> <char>
#> 1: 5.1 3.5 1.4 0.2 setosa
#> 2: 4.9 3 1.4 0.2 setosa
#> 3: 4.7 3.2 1.3 0.2 setosa
#> 4: 4.6 3.1 1.5 0.2 setosa
#> 5: 5 3.6 1.4 0.2 setosa
#> ---
#> 146: 6.7 3 5.2 2.3 virginica
#> 147: 6.3 2.5 5 1.9 virginica
#> 148: 6.5 3 5.2 2 virginica
#> 149: 6.2 3.4 5.4 2.3 virginica
#> 150: 5.9 3 5.1 1.8 virginica
对1到2列进行中心化标准化:
iris %>% mutate_vars(1:2,scale)
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> <num> <num> <num> <num> <fctr>
#> 1: -0.89767388 1.01560199 1.4 0.2 setosa
#> 2: -1.13920048 -0.13153881 1.4 0.2 setosa
#> 3: -1.38072709 0.32731751 1.3 0.2 setosa
#> 4: -1.50149039 0.09788935 1.5 0.2 setosa
#> 5: -1.01843718 1.24503015 1.4 0.2 setosa
#> ---
#> 146: 1.03453895 -0.13153881 5.2 2.3 virginica
#> 147: 0.55148575 -1.27867961 5.0 1.9 virginica
#> 148: 0.79301235 -0.13153881 5.2 2.0 virginica
#> 149: 0.43072244 0.78617383 5.4 2.3 virginica
#> 150: 0.06843254 -0.13153881 5.1 1.8 virginica
好的,我都觉得这个函数实在是太横了......
设计它是很久之前的事情,我都忘了有这种功能了,幸好当初帮助文档有好好写。
原文作者:;如有侵权,请联系管理员删除。