【问题标题】:Converting Factor Levels to Numbers将因子水平转换为数字
【发布时间】:2014-12-23 21:02:23
【问题描述】:

如果已经有答案,我深表歉意……我看了但找不到。

我正在尝试将因子矩阵转换为与列的每个因子值相对应的数字矩阵。很简单,对吧?然而,当我尝试这样做时,我遇到了各种非常奇怪的问题。

让我解释一下。这是一个示例数据集:

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)......所以让我们把它变成一个数据框......

> 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 次来逐列组装我的新矩阵...但是有更好的方法吗?

为什么它是矩阵形式而不是数据框形式时会出错? edit 实际上,这现在非常明显......在矩阵形式中,这些是字符,而不是因子。我的错。不过,关于数据框的问题仍然存在......

谢谢! (并指出我现有的答案是完全可以的)

【问题讨论】:

  • 你的例子是不是因素。小心你的命名法。
  • 您的示例是字符串矩阵,而不是因子。字符串没有任何因子级别等。
  • 我很抱歉。这个问题从一个导入的数据集开始,其中字符串被自动假定为因子(除非另有说明)。当我尝试重新创建它以供 stackoverflow 使用时发生错误。

标签: r matrix na


【解决方案1】:

看来您的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 是该列中的第一个(也是唯一一个)值。

【讨论】:

  • 我问的问题的答案很好......但显然我问了错误的问题。首先将 demodata2 制作成数据框(它会自动将字符字段放入因子中),然后您就有了我打算要问的问题。非常感谢您,我希望您能帮助解决这个额外的挑战。
  • @rucker - 更新数据更加简单。做demodata2[] &lt;- lapply(demodata2, as.numeric) 现在你在U 列中有1,因为每一列都是单独考虑的,因此B 是第一个(也是唯一的)值
  • 非常感谢!简单的?也许。但我一直在这个问题上四处走动,非常感谢您的帮助。
  • 嗯,更简单的代码就是我的意思:-)
【解决方案2】:

从机制上讲,这与'dim&lt;-' 的答案非常相似。更透明一点,但可能效率更低(也许?)。

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

【讨论】:

  • 哎呀,谢谢。原来as.vector() 也是不必要的。
  • 我猜它会比&lt;-dim 更有效,因为跳过了nrow 部分,我只是想对它有点精巧:)
  • @Gregor:我问的问题的答案很好……但显然我问错了问题。首先将 demodata2 变成一个数据框(它会自动将字符字段放入因子中),然后您就有了我打算要问的问题。非常感谢您,我希望您能帮助解决这个额外的挑战。
【解决方案3】:

或使用dim&lt;-

`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)

【讨论】:

  • 另一种改写行的方法:matrix(as.numeric(factor(demodata2)),ncol=ncol(demodata2))
  • @David Arenburg:我问的问题的答案很好......但显然我问了错误的问题。首先将 demodata2 制作成数据框(它会自动将字符字段放入因子中),然后您就有了我打算要问的问题。非常感谢您,我希望您能帮助解决这个额外的挑战。
【解决方案4】:
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 没有返回我预期的结果。)

【讨论】:

  • 我问的问题的答案很好......但显然我问了错误的问题。首先将 demodata2 制作成数据框(它会自动将字符字段放入因子中),然后您就有了我打算要问的问题。非常感谢您,我希望您能帮助解决这个额外的挑战。
猜你喜欢
  • 2015-01-27
  • 2017-07-18
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多