R语言基础--数据类型之因子-2019-06-26

R语言基础--数据类型之因子

参考:R语言笔记之数据类型2因子|RVDSD的个人笔记本

1.1 因子

因子(factor):是名义型变量或有序型变量,比较特殊。一个因子不仅包括分类变量本身还包括变量不同的可能水平(即使它们在数据中不出现)。

1.2 factor()用法

factor(x = character(), levels, labels = levels,
       exclude = NA, ordered = is.ordered(x), nmax = NA)
#factor (x,levels=sort(unique(x),na.last=TRUE), labels=lebels, exclude=NA, ordered=is.order (x))

其中,levels用于指定因子的可能水平;labels用于定义水平的名字;exclude指从向量x中剔除的水平值;ordered指因子的水平是否要排序,例如:

a <- factor(1:3)
a
## [1] 1 2 3
## Levels: 1 2 3

从上面的结果可以看出,这组数据中有3个数据,3个水平,分别为1,2,3。还有一种情况是,水平数大于实际的数据数,如下所示:

b<-factor(1:3,levels=1:5);b
## [1] 1 2 3
## Levels: 1 2 3 4 5

这组数据中有3个数据,有5个水平(其中两个水平没出现)。

1.3 factor数据的名称

c<-factor(1:3,labels=c("a","b","c"))
c
## [1] a b c
## Levels: a b 

str函数

str(c) #str即structure,紧凑的显示对象内部结构,即对象里有什么

# Factor w/ 3 levels "a","b","c": 1 2 3
 #c有三个水平,名字分别为a,b,c

1.4 将factor转化为其它类型

1.4.1 数值型
d<-c(1,10) #建立向量a,值为1,10
d
## [1]  1 10
fac<-factor(d)
fac #提取向量a的因子数,并赋给fac
## [1] 1  10
## Levels: 1 10
fac_value<-as.numeric(fac) #将fac转化为数值
fac
## [1] 1  10
## Levels: 1 10
1.4.2 字符型
e<-c("Male","Female")
e  #建立向量e,为字符型
## [1] "Male"   "Female"
fac_e<-factor(e);fac_e #提取向量b的因子,并且赋给fac_e
## [1] Male   Female
## Levels: Female Male
fac_e_value<-as.numeric(fac_e)#将fac_e转化为数值型
fac_e_value
## [1] 2 1
1.4.3 将factor转换为数值
as.numeric(as.character(fac))
## [1]  1 10

上述命令将fac(1,10)先转化为字符型,接着将字符型转化为数值型,如果直接将factor转换为numeric,容易出错,一般情况下就是先看factor转换为character,再转换为numeric。

1.5 将其它数据转换为factor

1.5.1 将字符转换为因子
a <- c("green","blue","green","yellow")
a <- factor(a)
levels(a) <- c(1,2,3,4)
ff <- factor(c("A","B","C",labels=c(1,2,3)))
ff
##  labels1 labels2 labels3 
##  A   B   C    1   2    3 
## Levels: 1 2 3 A B C
1.5.2 将数值转换为因子
b <- c(1,2,3,1)
b <- factor(b)
b
## [1] 1 2 3 1
## Levels: 1 2 3
1.5.3 提取可能的factor
ff <- factor(c(2,4),levels=2:5)
ff
## [1] 2 4
## Levels: 2 3 4 5
levels(ff)
## [1] "2" "3" "4" "5"
1.5.4 将连续型数据转换factor

以PlantGrowth数据集为例说明,先看一下这个数据集:

pg <- PlantGrowth[c(1,2,11,21,22),]
pg
# weight group
# 1    4.17  ctrl
# 2    5.58  ctrl
# 11   4.81  trt1
# 21   6.31  trt2
# 22   5.12  trt2

在这个案例中,我们使用cut()函数把一个连续型变量weight转化为分类变量wtclass,如下所示:

pg$wtclass <- cut(pg$weight,breaks=c(0,5,6,Inf))
pg
# weight group wtclass
# 1    4.17  ctrl   (0,5]
# 2    5.58  ctrl   (5,6]
# 11   4.81  trt1   (0,5]
# 21   6.31  trt2 (6,Inf]
# 22   5.12  trt2   (5,6]

我们为三个类设定了四个边界值,边界值可以包括正无穷(Inf)和负无穷(-Inf),如果一个值落在我们规定的区间外,它的类别将被设定为NA(缺失值),cut()函数的结果是一个因素,并且因子水平的名称是以生成的区间命名的,如下所示:

 str(pg)
'data.frame':   5 obs. of  3 variables:
 $ weight : num  4.17 5.58 4.81 6.31 5.12
 $ group  : Factor w/ 3 levels "ctrl","trt1",..: 1 1 2 3 3
 $ wtclass: Factor w/ 3 levels "(0,5]","(5,6]",..: 1 2 1 3 2

但是这个区间名称明显不太方便,我们可以更改一下,如下所示:

pg$wtclass <-cut(pg$weight,breaks=c(0,5,6,Inf),
                labels=c("Small","Medium","Large"))
# > pg
# weight group wtclass
# 1    4.17  ctrl   Small
# 2    5.58  ctrl  Medium
# 11   4.81  trt1   Small
# 21   6.31  trt2   Large
# 22   5.12  trt2  Medium

cut()函数生成的区间是左开右闭的,换句话说,它们不会包含最小值,但是它们包含了最大值,对于值最小的一类,可以通常设置参数include.lowest=TRUE来实现,这样它们就能同时包含最小值和最大值了,如果要让生成的区间是左闭右开的,需要设定参数right=FALSE,如下所示:

pg$wtclass <- cut(pg$weight,breaks=c(0,5,6,Inf),right=FALSE)

如果要更改不同因子的名称,例如将Small改为A,Medium改为B,Large改为C,那么就需要car中的recode函数,如下所示:

head(pg)
# weight group wtclass
# 1    4.17  ctrl   Small
# 2    5.58  ctrl  Medium
# 11   4.81  trt1   Small
# 21   6.31  trt2   Large
# 22   5.12  trt2  Medium
library(car)
pg$wtclass <- recode(pg$wtclass,"'Small'='A';'Medium'='B';'Large'='C'")
head(pg)
# weight group wtclass
# 1    4.17  ctrl       A
# 2    5.58  ctrl       B
# 11   4.81  trt1       A
# 21   6.31  trt2       C
# 22   5.12  trt2       B
1.5.5 生成指定的factor
seq()

在R的向量笔记中,提到了seq()函数用来生成某一条件的向量,这个函数在生成特定因子方面也有很重要的作用,用法为seq(length=, from=, to=),其中,length:指定生成个数,from:是指开始生成的点,to:截止点。

如下所示:

seq(length=10,from=10,to=100) # 生成从10到100的向量,一共10个
##  [1]10  20  3040  50  6070  80  90 100
# 上述命令等价于
seq(10,100,10)
##  [1]10  20  3040  50  6070  80  90 100
seq(1,10,by=2)
## [1] 1 3 5 7 9
seq(1,10,length=6)
## [1]  1.02.8  4.6  6.48.2 10.0
sequence(2:3) #产生以 2 和 3 结尾的序列数据
## [1] 1 2 1 2 3
rep()

用法:rep(P,N),表示重复生成P值N次,例如rep(a1:a2,a1:a2) #重复a1到a2,按a1产生a1次,按a2产生a2次,当rep(a1:a2,a1:a2)这种结构,后边的a1:a2要小于前者 如下所示:

rep(1,10)
##  [1] 1 1 1 1 1 1 1 1 1 1
rep(1:5,each=2, times=2) #重复1到5,每个元素重复二次,整个数列重复两次
##  [1] 1 1 2 2 3 3 4 4 5 5 1 1 2 2 3 3 4 4 5 5
rep(1:3,1:3) # 1重复1次,2重复2次,3重复3次
## [1] 1 2 2 3 3 3

gl函数

生成规则的因子序列,gl(k,n):k为水平数据,n是每个水平重复的次数。如下所示:

gl(3,5) #生成5个1,5个2,5个3,
##  [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
## Levels: 1 2 3
gl(3,5,length=30) #生成5个1,5个2,5个3,循环到30个,即:
##  [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
## Levels: 1 2 3
gl(2,6,label=c("Male","Female")) #生成Male与Female两个因子,各6个,共12个数据:
##  [1] Male Male   Male   Male Male   Male   Female Female Female Female
## [11] Female Female
## Levels: Male Female

1.6 有序因子

因子没有顺序,但也可以人为指定顺序。例如糖尿病类型Diabetes(Type1,Type2),就是2种类型没有顺序,但病人状态status(Poor,Imporved,Excellent)是有顺序的。案例如下:

patientID<-c(1,2,3,4)
age<-c(25,34,28,52)
diabetes<-c("Type1","Type2","Type1","Type1")
status<-c("Poor","Improved","Excellent","Poor")
diabetes<-factor(diabetes) #提取不同糖尿病类型的因子
status<-factor(status,order=TRUE) # 提取因子,并且有序
patientdata<-data.frame(patientID,age,diabetes,status)
patientdata
##   patientID age diabetes    status
## 11  25    Type1Poor
## 22  34    Type2Improved
## 33  28    Type1 Excellent
## 44  52    Type1Poor

注:字符型向量的因子水平默认依字母顺序创建。但在实际情况中并不常用,而是通过levels选项来指定因子顺序,使用factor(status, order = TRUE, levels = c(“Poor”, “Improved”, “Excellent”)),各个水平的赋值就为1 = Poor, 2 = Improved, 3 = Excellent。

或者是通过下面代码实现:

factor(status, ordered = TRUE, levels = c("Poor", "Improved", "Excellent"))
## [1] Poor      ImprovedExcellent Poor     
## Levels: Poor < Improved < Excellent
str(patientdata)#显示数据框的结构
## 'data.frame':    4 obs. of  4 variables:
##  $ patientID: num  1 2 3 4
##  $ age      : num25 34 28 52
##  $ diabetes : Factor w/ 2 levels "Type1","Type2": 1 2 1 1
##  $ status   : Ord.factor w/ 3 levels "Excellent"<"Improved"<..: 3 2 1 3
summary(patientdata)
##    patientID         age         diabetes       status 
##  Min.   :1.00Min.   :25.00   Type1:3Excellent:1  
##  1st Qu.:1.75   1st Qu.:27.25   Type2:1Improved :1  
##  Median :2.50   Median :31.00             Poor     :2  
##  Mean   :2.50Mean   :34.75                          
##  3rd Qu.:3.25   3rd Qu.:38.50                          
##  Max.   :4.00Max.   :52.00

1.7 factor的统计

如果一组数据有多个重复值,例如美国的每一个州都位于4个区域的中某一个,分别为东北,南、中北和西,则我们看一下内置的state数据集:

head(state.region)
## [1] South West  West  South WestWest 
## Levels: Northeast South North Central West
table(state.region)
## state.region
##Northeast         South North Central          West 
##9            16            12            1
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容