R语言 将因子水平转换为数字

zd287kbt  于 2023-01-22  发布在  其他
关注(0)|答案(5)|浏览(159)

我道歉,如果有一个答案已经有了这个...我找了,但找不到一个。
我试图将一个因子矩阵转换为一个数字矩阵,该矩阵对应于列中的每个因子值,这很简单,对吧?然而,当我尝试这样做时,我遇到了各种非常奇怪的问题。
让我来解释一下。下面是一个示例数据集:

demodata2 <- matrix(c("A","B","B","C",NA,"A","B","B",NA,"C","A","B",NA,"B",NA,"C","A","B",NA,NA,NA,"B","C","A","B","B",NA,"B","B",NA,"B","B",NA,"C","A",NA), nrow=6, ncol=6)
democolnames <- c("Q","R","S","T","U","W")
colnames(demodata2) <- democolnames

屈服:

Q   R   S   T   U   W  
[1,] "A" "B" NA  NA  "B" "B"
[2,] "B" "B" "B" NA  "B" "B"
[3,] "B" NA  NA  NA  NA  NA 
[4,] "C" "C" "C" "B" "B" "C"
[5,] NA  "A" "A" "C" "B" "A"
[6,] "A" "B" "B" "A" NA  NA

好吧,我想要的是

Q    R    S    T    U    W
1    1    2 <NA> <NA>    1    2
2    2    2    2 <NA>    1    2
3    2 <NA> <NA> <NA> <NA> <NA>
4    3    3    3    2    1    3
5 <NA>    1    1    3    1    1
6    1    2    2    1 <NA> <NA>

没问题,我们试试as.numeric(demodata2)

> as.numeric(demodata2)
 [1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
 [30] NA NA NA NA NA NA NA
 Warning message:
 NAs introduced by coercion

不太满意。我们只试一栏...

> as.numeric(demodata2[,3])
[1] NA NA NA NA NA NA
Warning message:
NAs introduced by coercion

编辑

这些实际上应该是因子,而不是字符(感谢@Carl Witthoft和@smci)......所以让我们把它变成一个 Dataframe ......

> demodata2 <- as.data.frame(demodata2)
> as.numeric(demodata2)
Error: (list) object cannot be coerced to type 'double'

不。但是等等......有趣的是......

> as.numeric(demodata2$S)
[1] NA  2 NA  3  1  2

好吧,是的。让我们验证一下,我可以通过数字调用列来实现这个功能:

> as.numeric(demodata2[,3])
[1] NA  2 NA  3  1  2

好的,我可以一列一列地迭代ncol次来组装我的新矩阵......但是有更好的方法吗?
为什么当它是矩阵形式的时候会呕吐,而不是 Dataframe ?〈-***edit***实际上,这现在很明显了...在矩阵形式中,这些是字符,而不是因子。我的错。问题仍然是关于 Dataframe 的,虽然...
谢谢!(给我指出一个现有的答案是完全可以的)

vfh0ocws

vfh0ocws1#

看起来你的U列应该是2对应于“B”,而不是1。请澄清这一点。
你可以试试match()

matrix(match(demodata2, LETTERS), nrow(demodata2), dimnames=dimnames(demodata2))
#       Q  R  S  T  U  W
# [1,]  1  2 NA NA  2  2
# [2,]  2  2  2 NA  2  2
# [3,]  2 NA NA NA NA NA
# [4,]  3  3  3  2  2  3
# [5,] NA  1  1  3  2  1
# [6,]  1  2  2  1 NA NA

您也可以通过以下方式获得此结果

m <- match(demodata2, LETTERS)
attributes(m) <- attributes(demodata2)

再看看m

对订正数据集的更新:

有关更新的数据,请尝试

demodata2[] <- lapply(demodata2, as.numeric) 
demodata2
#    Q  R  S  T  U  W
# 1  1  2 NA NA  1  2
# 2  2  2  2 NA  1  2
# 3  2 NA NA NA NA NA
# 4  3  3  3  2  1  3
# 5 NA  1  1  3  1  1
# 6  1  2  2  1 NA NA

现在U列中有了1,因为每列都是单独分解的,因此B是该列中的第一个(也是唯一的)值。

8cdiaqws

8cdiaqws2#

从机械上讲,这与'dim<-'的答案非常相似。稍微透明一点,但可能效率较低(也许?)。

matrix(as.numeric(factor(demodata2)), ncol = ncol(demodata2))

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    2   NA   NA    2    2
[2,]    2    2    2   NA    2    2
[3,]    2   NA   NA   NA   NA   NA
[4,]    3    3    3    2    2    3
[5,]   NA    1    1    3    2    1
[6,]    1    2    2    1   NA   NA
xwmevbvl

xwmevbvl3#

或者使用dim<-

`dim<-`(as.numeric(factor(demodata2)), c(nrow(demodata2), ncol(demodata2)))
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    1    2   NA   NA    2    2
# [2,]    2    2    2   NA    2    2
# [3,]    2   NA   NA   NA   NA   NA
# [4,]    3    3    3    2    2    3
# [5,]   NA    1    1    3    2    1
# [6,]    1    2    2    1   NA   NA

如果需要列名,则必须分两步完成,如

Res <- `dim<-`(as.numeric(factor(demodata2)), c(nrow(demodata2), ncol(demodata2)))
colnames(Res) <- colnames(demodata2)
t40tm48m

t40tm48m4#

apply(demodata2, 2, function(x) 
          as.numeric( factor(x ,levels=unique(as.vector(demodata2) ) ) ) )
#---------------
      Q  R  S  T  U  W
[1,]  1  2 NA NA  2  2
[2,]  2  2  2 NA  2  2
[3,]  2 NA NA NA NA NA
[4,]  3  3  3  2  2  3
[5,] NA  1  1  3  2  1
[6,]  1  2  2  1 NA NA

(通过得到错误的答案,我发现矩阵上的unique没有返回我所期望的结果。)

aamkag61

aamkag615#

demodata2成为 Dataframe 后,需要执行两个步骤:
步骤1:将您的字符转换为因子:
demodata2[sapply(demodata2, is.character)] <- lapply(demodata2[sapply(demodata2, is.character)], as.factor)
步骤2:使用as.integer将因子转换为数值:
demodata2[sapply(demodata2, is.factor)] <- lapply(demodata2[sapply(demodata2, is.factor)], as.integer)
结果:

> demodata2
   Q  R  S  T  U  W
1  1  2 NA NA  1  2
2  2  2  2 NA  1  2
3  2 NA NA NA NA NA
4  3  3  3  2  1  3
5 NA  1  1  3  1  1
6  1  2  2  1 NA NA

这会按照您的需要一次选择所有首选列,而不是一次选择一列。而且,这会单独对每列进行因子分解,因此您不会得到跨列的混合因子水平。

相关问题