R 中的因子 (Factors)


2022年3月30日, Learn eTutorial
2096

在我们上一个教程中,我们讨论并学习了 R 中的数据框。在本教程中,您将学习一种称为因子的特殊数据结构。因子最重要用途之一是统计建模。

具有统计学背景的人可能了解分类变量。分类变量与数值变量不同,它们只能取有限数量的不同值。否则,分类变量只能属于有限数量的类别。例如,在数据分析中,是/否、真/假、男/女是分类变量的一些类型。

R 是一种支持特定数据结构的编程语言,称为因子。当您将分类数据存储为因子时,您可以确保所有统计建模技术都能有效地处理此类数据。

什么是分类变量?

在深入学习因子教程之前,您需要了解分类变量的概念。您熟悉数据集这个词,数据集是数据的集合。R 编程语言使用数据集来处理、存储和分析数据,以进行数据分析和统计建模。这些数据集主要包含两种类型的变量:

  • 连续变量
  • 分类变量

连续变量是其值无限的变量。换句话说,它们包含不可数的值集。例如,温度、星系中的恒星数量、我们的体重都是连续变量。它可以在一个区间内取任何指定的值。

分类变量或离散变量是其值有限或包含一个不同组的变量。这意味着它们包含一个有限值集,可能有两个或多个类别(值)。分类变量有两种类型:**标称型**和**有序型**。

R Factor : categorical var

 

  1. 标称型变量:- 在标称型变量中,其类别没有固有的排序。例如:性别
  2. 有序型变量:- 有序型变量与标称型变量正好相反,它们确实具有分类值的特定排序。例如:温度。

考虑 GENDER,它构成了一个标称型分类变量,因为它的值只有两种可能,即 MALE 或 FEMALE。没有任何排序约束,无论 male 还是 female 都可以排在第一个位置。同样,考虑 WEEKS,weeks 只有 7 个值或类别,如 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY。

TEMPERATURE 可以分为 LOW、MEDIUM 和 HIGH 三类。它属于有序类别。值有一个特定的排序,从低温开始,然后是中温,最后达到高温。

categorical example

理解分类变量是学习 R 编程中因子之前的基本部分。在下一节中,我们将开始学习新的数据结构。

R 中的因子是什么?

因子是 R 编程中的一种特殊数据结构,用于存储分类变量或数据。因子是用于对数据进行分类并将其存储为级别的 Sata 对象。它可以存储整数和字符串。当分析具有唯一值的列时,因子非常有用。R 允许我们在有序因子和无序因子之间进行区分。

因子可以描述为:

  1. 因子用于存储 **分类变量**。
  2. 因子与 **级别** 属性相关联,该属性表示构成因子的元素。
  3. 因子是整数向量,它们会影响与之关联的级别。
  4. 可以使用 levels() 函数或 label 参数来更改因子级别。

例如,人们的血型是一个分类变量。它可以是 A、B、AB 和 O。假设您询问了 8 个人他们的血型,并记录了信息。假设您将收集到的信息存储为向量 **blood**。


#create a vector blood using c()
blood <- c("A","B","AB","O","AB","A","O","B")
print(blood)

该向量只包含一组预定义的值。


[1] "A"  "B"  "AB" "O"  "AB" "A"  "O"  "B"

如何在 R 中创建因子?

在 R 编程语言中,因子数据结构是使用一个称为 **factor()** 的内置函数创建的。**factor()** 函数接受一个向量作为输入。因子函数 **factor()** 从输入向量的分类变量创建因子。

因子具有与其中存储的唯一整数相关联的 **标签**。它们包含一组预定义的值,称为 **级别**。这些级别默认按字母顺序排序。不要混淆标签和级别,您将在接下来的会话中理解。

在 R 中创建因子的语法


factor(<x>,<levels>,<labels>,<exclude>,<ordered>,<nmax>)

其中 x、levels、labels、exclude、ordered、nmax 是因子的属性。

factor attrbs
属性 描述
X X 是输入向量,使用 **factor()** 转换为因子。
levels 级别表示一组唯一值,默认情况下取自输入向量 (x)。
labels 它是与每个整数或数字排序相对应的字符向量。
exclude 它指定需要从因子级别中排除的值。
ordered 逻辑属性,用于确定级别是有序因子还是无序因子。
nmax 它指定了最大级别的上限。
注意:级别、标签、排除、有序、nmax 在语法中是可选的。

示例:考虑我们在上面的会话中创建的示例 blood 中的输入向量。可以使用 factor() 来创建基于输入向量 blood 的因子。此处语法仅使用属性 X 作为输入向量。

blood 是对应于属性 X 的输入向量。


factor(blood)

此代码将产生如下所示的输出:


[1] A  B  AB O  AB A  O  B 
Levels: A AB B O

输出不包含双引号,不像上面主题下的向量 blood。在输出中,您可以确定对应于不同血型类别的级别。在用户未指定的情况下,级别由 R 默认设置为 A AB B O。

注意:级别按字母顺序排序。

程序员或用户也可以在创建因子时通过传递 level 参数来设置级别的顺序。以下是在因子语法中指定级别的步骤:

  1. 创建向量
  2. 通过提及向量的名称并设置级别(它是通过 c() 创建的向量,其中包含输入向量的唯一值)来创建向量的因子。

在 factor() 中设置级别的语法


Factor(<name of vector> ,level = c())

示例


#set level 
factor(blood,level = c("O","A","AB","B"))

此代码将产生带有预定义级别的输出。


[1] A  B  AB O  AB A  O  B 
Levels: O A AB B

level = c("O", "A", "AB", "B") 是创建的向量,它为输入 A B AB O AB A O B . 提供了唯一值。让我们比较输出以理解在 R 中创建因子数据结构时,有级别和无级别的区别。随 factor() 函数一起提供的 level = c("O", "A", "AB", "B")

使用用户定义的值设置级别。输入向量 blood 的默认级别为 Levels: A AB B O

而设置级别后,则为 Levels: O A AB B

无级别 有级别
factor(blood) factor(blood, level = c("O","A","AB","B"))

[1] A B AB O AB A O B

Levels: A AB B O

default

[1] A B AB O AB A O B

Levels: O A AB B

程序员设置的级别

注意:带级别的因子指定了顺序。

现在让我们看看如何为因子添加标签。标签是 factor() 函数中提供的可选向量,用于标记向量中的级别。带标签的因子指定了类别的新名称,在我们的示例 blood 中,这间接意味着标签更改了级别名称,如果级别发生更改,也会影响我们输入向量的名称。这是因为级别和相关的输入向量是相关联的。

在 factor() 中设置标签的语法


Factor(<name of vector> ,level = c(),label = c())

示例


#set label
factor(blood,level = c("A","B","AB","O"),label =c("BG_A","BG_B","BG_AB","BG_O"))

此代码将通过重命名因子元素来产生输出。


[1] BG_A  BG_B  BG_AB BG_O  BG_AB BG_A  BG_O  BG_B 
Levels: BG_A BG_B BG_AB BG_O

label 参数根据下图重命名了 factor() 元素,A 重命名为 BG_A,B 重命名为 BG_B,依此类推。

A B AB O AB A O B
BG_A BG_B BG_AB BG_O BG_AB BG_A BG_O BG_B

 

当您对字符向量调用因子函数时,R 会执行两项操作:

  1. 它会扫描向量(blood)以查看不同的类别,例如“A”、“AB”、“B”和“O”。
  2. 它将字符向量(blood)转换为整数向量。

这些整数对应于显示因子时使用的一组字符值。这可以通过显示结构来检查。可以使用 R 提供的内置函数 **str()** 来显示结构。


str(factor(blood))

它会产生一个输出,确定您正在处理的因子的结构,并显示有 4 个级别。


Factor w/ 4 levels "A","AB","B","O": 1 3 2 4 2 1 4 3

A 被编码为 1,因为它是第一个级别。AB 被编码为 2,它是第二个级别,依此类推。

请看图片以获得更清晰的图景。

4 level img

为什么在 R 因子中需要将字符转换为整数?

假设这些分类变量或向量可能包含长字符字符串。每次重复字符字符串可能需要大量内存。通过将字符转换为整数,实际上是用数值“A”对应 1 等来编码字符,这使其更简单且内存占用更少。

注意:请记住,因子是整数因子,每个整数对应一个类别或一个级别。

因此,R 会自动从您传入的向量推断因子级别,并按字母顺序对它们进行排序。R 还提供了设置级别顺序的机制。也就是说,可以通过在因子函数中传递 **level 参数** 来指定不同的级别顺序。


str(factor(blood, levels = c("O","B","AB","A")))

您可以看到 factor() 函数中的 level 参数指定了血型顺序。这里,“O”血型设置为级别 1,“B”血型设置为 2,“AB”为 3,“A”为 4。


Factor w/ 4 levels "O","B","AB","A": 4 2 3 1 3 4 1 2

当您比较不带级别参数和带级别参数的 factor() 的结构时,您会发现编码现在不同了。

factor with level img

R 因子中的函数

在 R 语言中,有一些内置函数允许用户获取有关 R 程序中使用到的因子的信息。下表描述了 R 中不同可用函数的函数功能。

函数 描述
is.factor() 用于确定一个变量是否为因子
as.factor() 将输入作为向量转换为因子。
is.ordered() 用于确定一个因子是否有序
ordered() 用于创建有序因子

在本教程的下一节中,您将详细了解每个函数。让我们开始讨论 ordered() 函数。

R 因子中的 Ordered() 函数

在 R 中,因子被分为有序和无序。默认情况下,R 为因子提供顺序。在某些情况下,level = c() 允许用户预定义输入向量的顺序。我们在上面会话的“如何创建因子”主题中用一个示例讨论了这一点,请回顾一下。

这里的想法是在 A 中引入 ordered() 函数。ordered() 函数允许创建有序因子。语法与我们创建 factor() 函数的方式相似。

使用 ordered() 函数对因子进行排序的语法


ordered(<name of vector> ,level = c())

考虑输入向量 X 为 blood


#create a vector blood using c()
blood <- c("A","B","AB","O","AB","A","O","B")

使用 ordered 函数语法对输入向量 blood 进行排序


#set order
ordered(blood,level = c("O","A","AB","B"))

应用 ordered() 函数后的结果输出为:


[1] A  B  AB O  AB A  O  B 
Levels: O < A < AB < B

如何在 R 编程语言中检查一个对象是否为因子?

在 R 编程语言中,内置函数 is.factor() 确定传递给函数的对象是否属于 R 中的因子。它会返回逻辑值 TRUE 或 FALSE 作为 is.factor() 的结果。您需要在函数括号 ( ) 中传递需要确定的对象或向量的名称。

在 R 中检查对象是否为因子的语法


is.factor(<object name to check >)

例如:下图检查 temp 是否为因子,将向量 temp 作为参数传递到 is.factor() 中。输出为 FALSE,因为 temp 只是使用 c() 函数创建的向量。

is.factor() false img

您可以使用 factor() 函数将此向量(temp)转换为因子。然后应用 is.factor() 将得到逻辑 TRUE 作为结果。请注意,创建的因子被赋值给名为 TEMP 的新向量。

is.factor() true img

识别对象为因子的步骤是:

  1. 创建向量(对象)输入
  2. 使用 is.factor() 检查向量(对象)

创建了两个向量 temp 和 TEMP 来观察每种情况的差异,方法是比较它们各自的输出。

步骤 描述 R 代码 输出
1  使用 c() 创建一个包含分类值 low, medium, high 的温度向量 temp > temp = c("low","medium","high") > temp [1] "low" "medium" "high"
2 使用 is.factor() 检查对象向量是否为因子   is.factor(temp) [1] FALSE   表示不是因子
3 使用 factor() 将向量 temp 转换为因子,并赋值给变量 TEMP TEMP <- factor(temp) [1] low medium high Levels: high low medium
4 再次使用 is.factor() 检查向量 TEMP(对象)是否为因子 is.factor(TEMP) [1] TRUE

让我们看看完整的源代码

使用 is.factor() 的程序


#A vector temp is created
temp = c("low","medium","high")
cat("The vector temp is \n :")
print(temp)

#is.factor() checks the object created is a factor or not
cat("Checks the vector temp is a factor \n :")
print(is.factor(temp)  )   #FALSE

#created a factor of temp vector and assigned to vector TEMP
TEMP <- factor(temp)
cat("The factor TEMP is \n :")
print(TEMP)

#is.factor() checks the object created is a factor or not
cat("Checks the factor TEMP is a factor \n :")
print(is.factor(TEMP) )    #TRUE

产生的输出是


The vector temp is 
 :[1] "low"    "medium" "high"  
Checks the vector temp is a factor 
 :[1] FALSE
The factor TEMP is 
 :[1] low    medium high  
Levels: high low medium
Checks the factor TEMP is a factor 
 :[1] TRUE

RStudio 中相同的代码片段和输出如下所示:

snippet img

如何在 R 中将变量转换为因子?

R 编程语言支持将变量的数据类型转换为因子或分类变量。as.factor() 函数允许将基本数据类型的字符/数值/整数变量(链接到基本数据类型)转换为因子数据结构。

语法


as.factor(x)

其中 x 是输入向量或变量。

例如,考虑 blood 变量的字符数据类型输入向量 (X),让我们使用 c() 函数创建向量 blood,其中包含字符数据类型的值。


#create a vector blood using c()
blood <- c("A","B","AB","O","AB","A","O","B")

让我们使用 as.factor() 将向量 blood 转换为因子。


#as.factor()
as.factor(blood)

转换为因子后的输出为:


[1] A  B  AB O  AB A  O  B 
Levels: A AB B O

factor() 函数以及 as.factor() 函数都将特定数据类型的变量返回为因子。as.factor() 的性能优于 factor() 函数。is.factor() 返回一个快速值。

如何在 R 中检查一个因子是否有序?

R 编程语言中的内置函数 is.ordered() 允许用户检查已定义的因子是否有序或无序。根据确定因子变量,返回逻辑 TRUE 或 FALSE 作为输出。如果变量是因子,则返回 TRUE,否则返回 FALSE。

语法


is.ordered(x)

我们在上一节创建了因子形式的 blood 变量,我们将在其中检查它是否有序。


#create a vector blood using c()
blood <- c("A","B","AB","O","AB","A","O","B")

#creates a factor
factor(blood)

#is.ordered() 
is.ordered(blood)

执行后的结果输出为:


[1] A  B  AB O  AB A  O  B 
Levels: A AB B O

[1] FALSE

输出返回 FALSE,表明因子无序。因子可以通过在创建因子时向 factor() 函数添加 levels 属性,或者使用 ordered() 函数来使其有序,ordered() 函数看起来与 factor() 函数相似但有所不同。回顾本教程的以上主题,我们已经在此处通过示例进行了讨论。

如何在 R 中删除因子元素?

在 R 中,exclude 参数用于排除因子中的元素。

考虑使用 factor() 函数创建的 TEMP 温度因子示例


#created a factor of temp vector and assigned to vector TEMP
TEMP <- factor(temp)
cat("The factor TEMP is \n :")
print(TEMP)

factor TEMP 生成的输出为:


The factor TEMP is 
 :[1] low medium high  
Levels: high low medium

上面的代码生成了一个因子数据结构 TEMP,其中包含 low、medium、high 因子,并且默认情况下,其级别指定为 high、low、medium。

现在,让我们像处理 level 和 labels 一样,将 exclude 参数包含到 factor() 函数中。exclude 参数包含需要从 TEMP 因子中删除的元素或因子。在这里,在我们的示例中,medium 被删除,因此它被赋给了双引号内的 excluded 参数。


TEMP <- factor(temp,exclude = "medium")

让我们看看排除 TEMP 因子中的 medium 后原始输出会发生什么。


[1] low  <na> high
Levels: high low

在输出中,您可以看到 medium 被排除,其位置用 R 编程语言中的保留词 表示,表示不适用。通过排除因子,级别也会被删除。

如何在 R 中生成因子级别?

要生成因子级别,有一个内置函数 gl()gl() 函数接受三个参数:u、v、labels。


gl(u,v,labels)

其中 u 是获取的级别数,V 是复制数,'labels' 是需要传递的向量。

以示例为例,它包含 3 个级别 (u),复制次数指定为 2 (v),并创建一个包含 low、high、medium 元素的向量并将其传递给 labels 参数。


gl(3,2,labels = c("low","medium","high"))

产生的输出是


[1] low    low    medium medium high   high  
Levels: low medium high


> gl(3,2,labels = c("low","medium","high"))
[1] low    low    medium medium high   high  
Levels: low medium high
> gl(3,2,labels = c("low","medium","high","average"))
[1] low    low    medium medium high   high  
Levels: low medium high average
> gl(4,2,labels = c("low","medium","high","average"))
[1] low     low     medium  medium  high    high    average average
Levels: low medium high average

如何在 R 中访问因子的组件?

在 R 编程语言中,可以通过方括号 [ ] 加上组件的索引号来访问因子中的任何组件。因此,索引有助于在 R 中访问因子的组件。

用于访问 R 组件的语法是:


<name of factor>[<index number of component>]

考虑本教程开头讨论的人的血型示例。我们将首先创建向量 blood,其中包含 8 种血型作为组件,并且默认情况下也会生成相应的级别。


> blood <- c("A","B","AB","O","AB","A","O","B")
> factor_blood = factor(blood)
> factor_blood 
[1] A  B  AB O  AB A  O  B 
Levels: A AB B O

现在让我们看看如何访问名为 factor_blood 的因子中的第四个组件。


factor_blood[4]

代码返回第四个(第 4)位置的元素。请记住,R 中的索引从 1 开始,而不是像其他语言那样从 0 开始。


[1] O
Levels: A AB B O

下图显示了 8 个组件 A、B、……、B 中,第四个位置的 O 组件被检索出来了。

factor components table1

如果您想从创建的因子中访问多个组件,可以按向量的形式传递所需的组件索引号,通过创建 c()。


factor_blood[c(1,5)]

输出是


[1] A  AB
Levels: A AB B O

factor components table2

当您在索引号前加上负号时会发生什么?


factor_blood[-1]

您将获得如下所示的输出:


[1] B  AB O  AB A  O  B 
Levels: A AB B O

通过在方括号中指定 -1,可以检索除第一个位置之外的所有元素。

factor_blood[-1] img

factor_blood[-5]

上面的代码从因子中删除了第五个组件 AB。比较输出和我们之前示例中使用的图片。


[1] A  B  AB O  A  O  B 
Levels: A AB B O

如何在 R 中修改因子组件?

在 R 编程中修改或更改组件的过程非常简单。您需要像我们在上一主题中讨论的那样访问因子的组件,在使用访问语法后,指定要分配给该特定组件的新值。

修改因子组件的语法


<name of factor>[index number] = <value to assign>

在给出的示例中:

  • 因子的名称是 factor_blood
  • 组件的索引号是 1
  • 要赋的值是“AB”

factor_blood[1]="AB"

该代码修改了 factor_blood 因子中的第一个组件,它用分配给它的新血型“AB”替换了原始组件“A”。