改变和重新排序因素
当使用默认值创建因子时,levels
由应用于输入的 as.character
形成,并按字母顺序排序。
charvar <- rep(c("W", "n", "c"), times=c(17,20,14))
f <- factor(charvar)
levels(f)
# [1] "c" "n" "W"
在某些情况下,对 levels
(字母/词汇顺序)的默认排序的处理是可以接受的。例如,如果一个人只想要频率,那将是结果:
plot(f,col=1:length(levels(f)))
但是如果我们想要 levels
的不同排序,我们需要在 levels
或 labels
参数中指定它(注意这里 order
的含义与有序因子不同,见下文)。根据具体情况,有许多替代方案可以完成该任务。
1.重新定义因素
如果可能,我们可以使用 levels
参数和我们想要的顺序重新创建因子。
ff <- factor(charvar, levels = c("n", "W", "c"))
levels(ff)
# [1] "n" "W" "c"
gg <- factor(charvar, levels = c("W", "c", "n"))
levels(gg)
# [1] "W" "c" "n"
当输入电平不同于所需的输出电平时,我们使用 labels
参数使得 levels
参数成为可接受输入值的滤波器,但将因子矢量的电平的最终值留作参数。labels
:
fm <- factor(as.numeric(f),levels = c(2,3,1),
labels = c("nn", "WW", "cc"))
levels(fm)
# [1] "nn" "WW" "cc"
fm <- factor(LETTERS[1:6], levels = LETTERS[1:4], # only 'A'-'D' as input
labels = letters[1:4]) # but assigned to 'a'-'d'
fm
#[1] a b c d <NA> <NA>
#Levels: a b c d
2.使用 relevel
功能
当有一个特定的 level
需要是第一个我们可以使用 relevel
。例如,在统计分析的背景下,当测试假设需要 base
类别时,就会发生这种情况。
g<-relevel(f, "n") # moves n to be the first level
levels(g)
# [1] "n" "c" "W"
可以证实 f
和 g
是相同的
all.equal(f, g)
# [1] "Attributes: < Component `levels`: 2 string mismatches >"
all.equal(f, g, check.attributes = F)
# [1] TRUE
3.重新排序因素
有些情况下,我们需要根据数字,部分结果,计算统计数据或先前的计算来计算 levels
。让我们根据 levels
的频率重新排序
table(g)
# g
# n c W
# 20 14 17
reorder
函数是通用的(参见 help(reorder)
),但在这种情况下需要:x
,在这种情况下是因子; X
,与 x
相同长度的数值; 和 FUN
,一个应用于 X
的函数,由 x
的级别计算,它确定 levels
的顺序,默认增加。结果与其重新排序的级别相同。
g.ord <- reorder(g,rep(1,length(g)), FUN=sum) #increasing
levels(g.ord)
# [1] "c" "W" "n"
为了得到降序,我们考虑负值(-1
)
g.ord.d <- reorder(g,rep(-1,length(g)), FUN=sum)
levels(g.ord.d)
# [1] "n" "W" "c"
该因素再次与其他因素相同。
data.frame(f,g,g.ord,g.ord.d)[seq(1,length(g),by=5),] #just same lines
# f g g.ord g.ord.d
# 1 W W W W
# 6 W W W W
# 11 W W W W
# 16 W W W W
# 21 n n n n
# 26 n n n n
# 31 n n n n
# 36 n n n n
# 41 c c c c
# 46 c c c c
# 51 c c c c
当存在与因子变量相关的定量变量时,我们可以使用其他函数对 levels
进行重新排序。让我们看一下 iris
数据(help("iris")
获取更多信息),通过使用它的平均值来重新排序 Species
因子 35。
miris <- iris #help("iris") # copy the data
with(miris, tapply(Sepal.Width,Species,mean))
# setosa versicolor virginica
# 3.428 2.770 2.974
miris$Species.o<-with(miris,reorder(Species,-Sepal.Width))
levels(miris$Species.o)
# [1] "setosa" "virginica" "versicolor"
通常的 boxplot
(比如说:with(miris, boxplot(Petal.Width~Species)
)会按顺序显示 especies: setosa , versicolor 和 virginica 。但是使用有序因子我们得到的物种按其平均值排序 38:
boxplot(Petal.Width~Species.o, data = miris,
xlab = "Species", ylab = "Petal Width",
main = "Iris Data, ordered by mean sepal width", varwidth = TRUE,
col = 2:4)
此外,还可以更改 levels
的名称,将它们组合成组,或添加新的 levels
。为此,我们使用相同名称 levels
的功能。
f1<-f
levels(f1)
# [1] "c" "n" "W"
levels(f1) <- c("upper","upper","CAP") #rename and grouping
levels(f1)
# [1] "upper" "CAP"
f2<-f1
levels(f2) <- c("upper","CAP", "Number") #add Number level, which is empty
levels(f2)
# [1] "upper" "CAP" "Number"
f2[length(f2):(length(f2)+5)]<-"Number" # add cases for the new level
table(f2)
# f2
# upper CAP Number
# 33 17 6
f3<-f1
levels(f3) <- list(G1 = "upper", G2 = "CAP", G3 = "Number") # The same using list
levels(f3)
# [1] "G1" "G2" "G3"
f3[length(f3):(length(f3)+6)]<-"G3" ## add cases for the new level
table(f3)
# f3
# G1 G2 G3
# 33 17 7
- 有序因素
最后,我们知道 ordered
因子与 factors
不同,第一个用于表示序数据,第二个用于标称数据。首先,改变 levels
对有序因子的顺序是没有意义的,但我们可以改变它的 labels
。
ordvar<-rep(c("Low", "Medium", "High"), times=c(7,2,4))
of<-ordered(ordvar,levels=c("Low", "Medium", "High"))
levels(of)
# [1] "Low" "Medium" "High"
of1<-of
levels(of1)<- c("LOW", "MEDIUM", "HIGH")
levels(of1)
# [1] "LOW" "MEDIUM" "HIGH"
is.ordered(of1)
# [1] TRUE
of1
# [1] LOW LOW LOW LOW LOW LOW LOW MEDIUM MEDIUM HIGH HIGH HIGH HIGH
# Levels: LOW < MEDIUM < HIGH