如何理解R中因子(factor)的概念? 刚开始学R,对因子的概念弄不清楚。怎样辨别一个变量是因子还是类别型变量?另外,怎样理解stringsAsFactors=FALSE这个参数,什么情况该加什么情况不该加?谢谢大神!
统计学里面定类变量,定序变量,定距变量和定比变量,这是是层层递进的关系,关于这个有大神讲的比我好多了。
这里楼主纠结的在于前两个,定类变量和定序变量,我的理解是factor可以将定类变量变成定序的,这样就可以适用于定序的统计方法。
stringAsFactor 建议一直等于false,关于这点Hadley也有说明 分别在开发 dplyr/tibble 和readr包时有说明 ,不信你仔细去阅读这些包的vignettes。另外readr包默认读入文本类型数据不自动转factor,数据读入还是建议使用这个包~
我们先从因子的起源说起。
我们生活中经常会遇到分类的问题,比如从性别上分能分成两类:男人和女人。如果从年龄上划分,又可将人群分为青年人(<-30岁),中年人(30-60岁),老年人(>60岁)。我们可以将这一表示类别的数据称为分类数据。
分类数据有着重要的意义,比如我们可以对现在流行的共享单车用户按下面的类别进行分组研究。
对数据进行分组研究后,我们会发现90%用户在目的地与地铁/公交站相距3000米内时选择使用共享单车,共享单车成为最有效的“最后一公里”解决方案。
类别数据对于分组数据研究非常有用。那么,在数据分析中是如何来表示类别数据呢?
这个问题也源自大数据社群的内部讨论。今天我们以数据分析R语言为例,看下在R中是如何表示类别数据的。




1. 如何表示分类数据?
在R中数据的分类是用因子数据类型(factor)来表示的。那么什么是因子呢?
因子被用来表示类别数据,因此也被称为“类别变量”。举个具体的例子吧,你所在工作单位老板特别变态,要求每天上班打卡(我个人是非常痛恨上班打卡这种变态的行为的)。




你的老板电脑里就有所有员工每天打卡的记录数据,其中有姓名(name),性别(sex),是否打卡(card)等列。




这里的性别(男,女)有2个类别,就可以把姓名这一列作为因子变量来处理。而姓名这一列因为不是类别,毕竟每个人的姓名是不一样的,即使有两个人的姓名重名(加入都叫猴子),这两个人也不属于同一类。
不过也确实,这个世界说白了就是男人与女人的世界。




现在你明白了,因子就是用于表示一组数据中的类别,可以记录这组数据中的类别名称及类别数目。
在R中使用factor函数来创建因子,下面我们创建了性别向量为因子。




2. 使用分类数据的意义是什么?
- 实现研究对象的分组、分类计算
很多时候,一些模型参数都需要传入变量类型为因子。同时,绘图时候因子可以帮助你自动实现分组绘图。下面我们具体看下。
根据一开始的例子,我们创建了一个打卡记录数据。




你会发现,只要是列里的值是字符串的,R都会自动将该列转换为因子类型。例如上面的姓名(name)列转换为因子类型,姓名叫“猴子”的有2个人。同样的,性别(sex)列也列出了每个类别的数据条数。
但是,姓名不是类别,我们不希望这一列是因子类型,需要将姓名这一列转换为字符串类型。








绘图后,我们看到每个性别的人数个数。现在你能理解了因子的作用了吧。正是因为性别(sex)这一列是因子类型,我们才能绘图是自动按照类别进行分组,计算出每一个类别的数目。
- 类别数据能帮助我们自动发现错误数据
上面我们绘制的柱状图,你会发现性别里有个类别(feamle)并不是我们想要的,这有可能是原始数据本身的错误。




这时候,我们需要查找原始数据的值进行校验修改。校验后我们发现值为“feamle”的数据对应的值应该为性别“男”。我们现在来修改下。




删除废弃的类别后,你会发现性别(sex)这一列只有两个类别了。




3. 类别如何排序呢?
因子的类别默认排序都是按字母顺序来排序。但是有时候我们想制定类别的顺序。
例如学校让学生给老师教学打评分的类别有:良好,同意,不满意,非常同意,非常不满意。其实,按照正常的顺序你希望是这样的:非常不满意,不满意,良好,同意,非常同意。
下面我们以性别为例,将这一列的类别按照:女,男顺序来排序。








4. 因子的几个问题
1)数值类型转换成因子
直接用as.numeric转换会有问题,转换后的内容不是你想要的:




2)因子中 levels和lables的区别
levels代表原始类别名称,lables相当于对类别名称进行重命名。
下面我们将原始数据中所以类别为女的重命名为“female”,男的重命名为“male”。




上面只是列举了数据分析R语言中的分类问题处理。其实其他编程语言Python也类似。一个领域中的陌生知识如果搞不明白,我们就可以联想下这个知识可以和现实生活中的哪些常识对应起来,因为知识的发明根本上是为了解决生活中的问题的。
这个世界也正是有了男人和女人才变的那么有趣。




漫画来自Brightside
————领取福利分界线——————
我是猴子,中科院硕士/IBM软件工程师/豆瓣8分《数据分析思维》作者,我和知乎知学堂研职在线联合出品的「数据分析训练营」即将开课,3天带你掌握数据分析实用技巧,包含课程+实战带练,工作提效、升职加薪必备神器!
报名还有独家Excel自学资料领取,点击开启数据分析升职加薪密码:
因为有需要,研究了一下R里面因子这个概念。
一、定义
标准定义: 因子用来存储类别变量和有序变量,这类变量不能用来计算而只能用来分类或者计数。
举个例子来看。我们在取用数据的时候,肯定会有很多维度,比如我在整理某个事件的媒体传播情况,会有这些维度:标题、媒体、网址、阅读量等等。




这些维度里面,有文本格式的,也有数字格式的。
这个时候因子的概念就引入了,我把这些不管是文本格式的数据列还是数字格式的数据列,都可以统一包装成因子数据格式,差不多就可以这么理解它。(后面讲为什么要这么做)
二:简要介绍一下因子
你可以这么创建一个因子:
factor(x = character(), levels, labels = levels,exclude = NA, ordered = is.ordered(x), nmax = NA)
因为我们只是为了理解这东西,所以先只看levels和labels这两个参数。
首先是因子水平levels,下面我创建一个新闻的来源维度,w代表,m代表网媒:
source<- factor(c('w','w','m','m','m'),levels=c('w','m'))
因子source的值是向量c(‘w’,’w’,’m’,’m’,’m’),因子水平是c(‘w’,’m’):
打印出来是这个样子。




这里的levels规定了因子的取值范围,如果我在创建值向量中多一个levels范围外的“y”,他就显示不出来了,显示为<NA>。




然后是因子水平的标签labels,使用factor函数创建因子,可以使用labels参数为每个因子水平添加标签,labels参数的字符顺序,要和levels参数的字符顺序保持一致,例如:
source<- factor(c('w','w','m','m','m'),levels=c('w','m'),labels=c('weixin','media'))
然后他会是这样的。




三、为什么要这么设定,因子有什么用?
因子其实是把序列中的数据看成是一个类别、等级,或者说就是一个点,比如媒体,可以有网媒、,阅读量,本身是个连续的数据,这里每一个阅读量,都被看成一个类别(虽然这类数值不适合作为类别,更适合作为连续数值处理)
类别数据,可以帮你查看有哪些类别:




查看有多少类别:




具体应用中还有很多用,本文只为了了解,所以不继续展开。
四、实际操作中遇到过的坑:
在创建具有文本数据列的任何数据框时,R语言将文本列视为分类数据并在其上创建因子。
这就是为什么,我们读取CSV或者EXCEL时,经常莫名其妙读进来的是因子,完全不知道怎么处理。
你可以用str()先查一下数据是什么格式的,比如我的source就是factor因子




所以怎么办呢?第一个办法,比如读取CSV的时候,在后面加上stringsAsFactors = FALSE,读出来的数据就不会转换成因子格式了。
data2 <- read.csv("文件路径",sep=",",header = FALSE,stringsAsFactors = FALSE)
第二个方法,读进来之后内容也是可以转的,直接用as.character()就可以将数据转成文本




介绍到这里,一般的使用应该是没问题了。
最后吐槽下,觉得R没有Python顺手。
首先,理论上你可以用字符变量(character)完全取代因子变量(factor)。如果总是遇到麻烦,用as.character函数转化,然后按照字符变量处理就好了。正如别的小伙伴所讲,它是分类变量的一种表示方式,但是在计算机存储上,其实它更偏向于数值存储。你可以试试:




因子变量有什么好处呢?答案:节省内存。可以尝试:




明明是同样的东西,因子变量存储空间更小。因此很多代码中(特别是老代码,新的可能会帮助自动转化),需要传入的参数是因子变量。
通俗一点,就是如果性别这一列是“男”和“女”两个类别,那么我们现在用1代表男,2代表女,然后用来表示性别这一列。
相信很多R
用户都对因子这种数据结构,有一种云里雾里的感觉,不知道什么时候用,为什么用,用的时候也多是凭感觉(大概应该用因子更合适)。
本篇就为大家解除这些困惑。
————————————
先看一下数据的划分:




R
提供了因子这一数据结构(容器),专门用来存放名义型和有序型的分类变量。因子本质上是一个带有水平 (level
) 属性的整数向量,其中“水平”是指事前确定可能取值的有限集合。例如,性别有两个水平:男、女。
直接用字符向量也可以表示分类变量,但它只有字母顺序,不能规定想要的顺序,也不能表达有序分类变量。所以,有必要把字符型的分类变量转化为因子型,这更便于对其做后续描述汇总、可视化、建模等。
1. 创建与使用因子
函数 factor()
用来创建因子,基本格式为:
factor(x, levels, labels, ordered, ...)
x
:为创建因子的数据向量;levels
:指定因子的各水平值,默认为x
中不重复的所有值;labels
:设置各水平名称 (前缀) ,与水平一一对应;ordered
:设置是否对因子水平排序,默认FALSE
为无序因子,TRUE
为有序因子;
该函数还包含参数 exclude
:指定有哪些水平是不需要的 (设为NA
) ;nmax
设定水平数的上限。
若不指定参数levels
,则因子水平默认按字母顺序。
比如,现有6个人的按等级的成绩数据,先以字符向量创建,并对其排序:
x = c("优", "中", "良", "优", "良", "良") # 字符向量
x




sort(x) # 排序是按字母顺序




它的顺序只能是字母顺序,如果想规定顺序:中、良、优,正确的做法就是创建成因子,用levels
指定想要的顺序:
x1 = factor(x, levels = c("中", "良", "优")) # 转化因子型
x1




as.numeric(x1) # x的存储形式: 整数向量




注意:不能直接将因子数据当字符型操作,需要用as.character()
转化。
转化为因子型后,数据向量显示出来(外在表现)与原来是一样的,但内在存储已经变了。因子型是以整数向量存储的,将各水平值按照规定的顺序分别对应到整数,将原向量的各值分别用相应的整数存储,输出和使用的时候再换回对应的水平值。整数是有顺序的,这样就相当于在不改变原数据的前提下规定了顺序,同时也节省了存储空间。




变成因子型后,无论是排序、统计频数、绘图等,都有了顺序:
sort(x1)




table(x1)




library(tidyverse)
ggplot(tibble(x1), aes(x1)) +
geom_bar()




用levels()
函数可以访问或修改因子的水平值(将改变数据的外在表现):
levels(x1) = c("Excellent", "Good", "Fair") # 修改因子水平
x1




有时候你可能更希望让水平的顺序与其在数据集中首次出现的次序相匹配,设置参数 levels = unique(x)
.
转化为因子型的另一个好处是,可以”识错”:因子数据只认识出现在水平值中的值,否则将识别为NA
.
很多人将因子固有的顺序与有序因子混淆,二者不是一回事:
- 上述反复提到的顺序,可称为因子固有的顺序,正是有了它,才能方便地按想要的顺序排序、统计频数、绘图等;
- 而无序因子与有序因子,是与变量本身的数据类型相对应的,名义型(无顺序好坏之分的分类变量)用无序因子存放,有序型 (有顺序好坏之分的分类变量)用有序因子存放,该区分是用于不同类型的数据,建模时适用不同的模型。
示例的成绩数据是有好坏之分的,创建为有序因子:
x2 = factor(x, levels = c("中", "良", "优"), ordered = TRUE)
x2




如果对x2
做排序、统计频数、绘图,你会发现与无序因子时没有任何区别。它们的区别体现在对其建模时适用的模型不同。
2. forcats
包
tidyverse
系列中的 forcats
包是 专门为处理因子型数据而设计的,提供了一系列操作因子的方便函数:
as_factor()
: 转化为因子,默认按水平值的出现顺序fct_count()
:计算因子各水平频数、占比,可按频数排序fct_c()
: 合并多个因子的水平
改变因子水平的顺序:
fct_relevel()
手动对水平值重新排序fct_infreq()
: 按高频优先排序fct_inorder()
: 按水平值出现的顺序fct_rev()
: 将顺序反转fct_reorder()
: 根据其它变量或函数结果排序 (绘图时有用)
修改水平:
fct_recode()
: 对水平值逐个重编码fct_collapse()
: 推倒手动合并部分水平fct_lump_*()
: 将多个频数小的水平合并为其它fct_other()
: 将保留之外或丢弃的水平合并为其它
增加或删除水平:
fct_drop()
: 删除若干水平fct_expand
: 增加若干水平fct_explicit_na()
: 为NA
设置水平
大家需要明白这样一个基本逻辑:操作因子是操作一个向量,该向量更多的时候是以数据框的一列的形式存在的。
所以,下面简单演示一下更常用的操作数据框中的因子列。
mpg
是汽车数据集,class
列是分类变量车型,先统计各种车型的频数,共有7类;对该列做因子合并,合并为5类+Other类再统计频数,频数少的类合并为Other
类:
count(mpg, class)




mpg1 = mpg %>%
mutate(class = fct_lump(class, n = 5))
count(mpg1, class)




若直接对class
各类绘制条形图,是按水平顺序,频数会参差不齐;改用根据频数多少排序,则条形图变的整齐易读:
library(patchwork)
p1 = ggplot(mpg, aes(class)) +
geom_bar()
p2 = ggplot(mpg, aes(fct_infreq(class))) +
geom_bar()
library(patchwork)
p1 | p2




本篇内容是原《R语言编程:基于tidyverse》书中的最新改写版,更多信息,欢迎参阅:
张敬信:《R语言编程—基于tidyverse》新书信息汇总591 赞同 · 76 评论文章741 赞同 · 89 评论文章
——————————
版权所有,欢迎转载,禁止用于任何出版
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/8663.html