我正在寻找一个函数来获取因子变量的原始映射表。我导入一个 Rdata 文件。我有一个名为“FactVar”的因子变量。我知道“FactVar”的映射表如下:
"010025" -> city1
"015146" -> city2
"048017" -> city3
"082053" -> city4
在我的数据框中,“FactVar”数据如下(前 5 个案例):
1: city1
2: city3
3: city4
4: city1
5: city3
所以,我的 df 中没有“city2”。我可以使用哪个函数来获取原始映射表?它在我的 Rdata 文件中可用吗?
谢谢你
编辑: 我尝试用一个更好的例子来澄清我的问题。我有一个调查问题,可能的答案如下:
1: "Yes"
2: "No"
8: "Don't Know"
9: "Not Applicable"
我创建一个因子变量“FactVar”:
Var <- c(1,2,1,2,2,2,1,8,1,2)
FactVar <- factor(Var, levels=c(1,2,8,9), labels=c("Yes", "No", "Don't Know", "Not Applicable")
如您所见,在我的 Rdata 文件中,我有一个因子变量,其中没有数据链接到“不适用”级别。我怎样才能得到我的调查问题中的原始映射表?
我认为答案是“不”。我没有任何明确的信息来支持这一点,但即使仔细阅读
factor
和相关函数的文档,我也看不到任何方法来恢复原始级别,除非您单独存储它们(例如,作为 attribute
,或在创建因子时保存原始函数调用。
坦率地说,我认为这在程序设计中有些疏忽,虽然这绝对是一种边缘情况(我以前从未考虑过),但我将在这个问题上悬赏并希望它引起了 Dirk Eddelbuettel 或其他 R 大师之一的注意。
编辑:我没有看到“添加赏金”按钮。也许几天后就会出现(希望我记得)。
我之前有过这个问题,在这里得到了解答:如何在 R 中访问实际的内部因子查找哈希表
抱歉,我没有足够的声誉来将此放入评论中。
str(FactVar)
将返回级别及其标签之间的映射,如下所示:
FactVar <- factor(Var, levels=c(1,2,8,9), labels=c("Yes", "No", "Don't Know", "Not Applicable
并将包括未使用因素的标签和水平。
我有一个稍微不同的问题,但基于例如shadowtalker的answer,我认为答案是相同的:你无法获得关联。
我有兴趣将变量转变为因子并保留原始数据。看来我必须创建一个新变量并保留两者。
R 文档中的因子帮助页面指出
要将因子 f 转换为近似其原始数值,建议使用 as.numeric(levels(f))[f],它比 as.numeric(as.character(f)) 稍微高效一些。
例如:
> v <- c( 0, 0, 3, 0, 6, 6 )
>
> f1 <- factor( x = v, levels = c( 0, 3, 6, 9 ) )
>
> as.numeric( levels( f1 ) )[f1]
[1] 0 0 3 0 6 6
>
> as.numeric( as.character( f1 ) )
[1] 0 0 3 0 6 6
但是,如果因子被标记,以上方法都不起作用:
> f2 <- factor( x = v, levels = c( 0, 3, 6, 9 ), labels = c( "a", "b", "c", "d" ) )
>
> as.numeric( levels( f2 ) )[f2]
Warning: NAs introduced by coercion
[1] NA NA NA NA NA NA NA NA NA NA
>
> as.numeric( as.character( f2 ) )
Warning: NAs introduced by coercion
[1] NA NA NA NA NA NA NA NA NA NA
如果我们看一下
levels()
和 as.character()
给出的内容,这是显而易见的:
> levels( f2 )
[1] "a" "b" "c" "d"
>
> as.numeric( levels( f2 ) )
Warning: NAs introduced by coercion
[1] NA NA NA NA
>
> as.character( f2 )
[1] "a" "a" "b" "a" "c" "c"
如果我们只使用
as.numeric()
,我们会得到由factor()
创建的新级别值:
> as.numeric( f2 )
[1] 1 1 2 1 3 3
举个例子:
> Var <- c(4,5,4,5,8)
> FactVar <- factor(Var, levels=c(4,5,8,9), labels=c("Yes", "No", "Don't Know", "Not Applicable"))
> FactVar
[1] Yes No Yes No Don't Know
Levels: Yes No Don't Know Not Applicable
我们可以使用 FactVar
函数查看 R 维护的关于
unclass()
的剩余信息的 all:
> unclass(FactVar)
[1] 1 2 1 2 3
attr(,"levels")
[1] "Yes" "No" "Don't Know" "Not Applicable"
您可以看到,R 没有保留原始
c(4,5,4,5)
数据。它只是获取原始数据,找到唯一的“级别”和从 1 开始连续的数字。然后将因子存储为值范围从 1 到级别数的整数向量。事实上,包含 4、5 和 8 的原始数据已完全丢失,因此无法恢复。
最后,R 中因子的预期目的是创建一个整数向量范围从 1 到 n_levels,其中整数代表一个命名类别。最常见的是,这用于将字符向量编码为数字类别。
在我看来,将整数转换为因子可能只在少数情况下有用。实际上,您所做的就是将整数(在示例中为 4、5 和 8)重新映射到一组新整数(1、2 和 3),然后显示与新整数组关联的名称.
所以我不认为这是设计限制。我认为也许人们希望因素做的事情超出了设计的初衷。
如果您想保留原始值并具有与其关联的类名称,也许只需命名原始向量即可?
> Var <- c(4,5,4,5,8)
> hash <- c(Yes = 4, No = 5, `Don't Know` = 8, `Not Applicable` = 9)
> namedVar <- hash[match(Var, hash)]
> namedVar
Yes No Yes No Don't Know
4 5 4 5 8
另一种解决方案是将两者放入 data.frame 中:
> Var <- c(1,2,1,2,2,2,1,8,1,2)
> data.frame(Var = Var, FactVar = factor(Var, levels=c(1,2,8,9), labels=c("Yes", "No", "Don't Know", "Not Applicable")))
Var FactVar
1 1 Yes
2 2 No
3 1 Yes
4 2 No
5 2 No
6 2 No
7 1 Yes
8 8 Don't Know
9 1 Yes
10 2 No
>
不确定我明白你的意思。 您可以指定因子水平的标签。
df$FactVar <- factor(df$FactVar, levels=c(paste0("city", 1:4))) # assuming you go up to 'city4'
重点是,您可以使用函数中的
levels
参数以任何顺序指定级别 factor