【问题标题】:Integer64 class doesn't survive reshape2 melt functionInteger64 类无法在 reshape2 熔化功能中存活
【发布时间】:2013-02-15 10:37:51
【问题描述】:

我不知道这是integer64(来自bit64)问题,还是融化问题(来自reshape2,但如果我尝试重塑包含integer64 数据的data.frame,那么类信息在此过程中被销毁并恢复为双重表示:

library(bit64)
library(reshape2)

DF = data.frame(I =letters, Num1 = as.integer64(1:26), Num2 = as.integer64(1:26))
DFM = melt(DF, id.vars = "I")

sapply(DF, class)
sapply(DFM, class)

给予:

> sapply(DF, class)
          I        Num1        Num2 
   "factor" "integer64" "integer64" 
> sapply(DFM, class)
        I  variable     value 
 "factor"  "factor" "numeric" 

而且由于 integer64 在下面是 double 的,所以数据被“损坏”了

> DF
   I Num1 Num2
1  a    1    1
2  b    2    2
3  c    3    3
4  d    4    4
5  e    5    5
...
> DFM
   I variable         value
1  a     Num1 4.940656e-324
2  b     Num1 9.881313e-324
3  c     Num1 1.482197e-323
4  d     Num1 1.976263e-323
5  e     Num1 2.470328e-323
6  f     Num1 2.964394e-323

这是什么原因造成的?这是integer64 问题还是melt 问题?在创建类时可以做些什么来避免这种事情?

【问题讨论】:

  • 我无法重现您的问题:sapply(DFM, class) 给出了“factor”、“factor”和“integer64”
  • 我可以重现它。
  • 有趣,那么我们之间有什么不同呢?是否有一些版本信息或其他我可以提供的有用信息?
  • @Corone,看看page 9 here。文档说明了限制,并且清楚地说明了基本 R 函数的一些问题。例如,is.vector(x=as.integer64(1:5)) 将返回 FALSE!
  • @Arun is.vector 是一条红鲱鱼:对于任何具有属性的向量都是错误的。 is.atomic 是更重要的测试。

标签: r class dataframe reshape2


【解决方案1】:

这似乎是软件包的限制,在他们的文档here on page 9 中也提到了这一点。例如:

x <- data.frame(a=as.integer64(1:5), b=as.integer64(1:5))
> x
#   a b
# 1 1 1
# 2 2 2
# 3 3 3
# 4 4 4
# 5 5 5

> unlist(x)

#            a1            a2            a3            a4            a5            b1 
# 4.940656e-324 9.881313e-324 1.482197e-323 1.976263e-323 2.470328e-323 4.940656e-324 
#            b2            b3            b4            b5 
# 9.881313e-324 1.482197e-323 1.976263e-323 2.470328e-323 

> as.matrix(x)
#                  a             b
# [1,] 4.940656e-324 4.940656e-324
# [2,] 9.881313e-324 9.881313e-324
# [3,] 1.482197e-323 1.482197e-323
# [4,] 1.976263e-323 1.976263e-323
# [5,] 2.470328e-323 2.470328e-323

x <- as.integer64(1:5)

> is.vector(x)
# [1] FALSE

> as.vector(x)
# [1] 4.940656e-324 9.881313e-324 1.482197e-323 1.976263e-323 2.470328e-323

【讨论】:

    【解决方案2】:

    重置类似乎“纠正”了结果,见下文。但是,正如讨论中提到的,如果数值还包含integer64 以外的其他类型,这很可能不起作用。

    > class(DFM$value) <- "integer64"
    > DFM
       I variable value
    1  a     Num1     1
    2  b     Num1     2
    3  c     Num1     3
    

    【讨论】:

    • 谢谢,这在类似的情况下帮助了我。只是一个小警告,NAs 变成了9218868437227407266...
    【解决方案3】:

    我也可以复制。

    不是解决方案,但问题似乎发生在melt.data.frame函数的以下行:

    value <- unlist(unname(data[var$measure]))
    

    在您的示例中,这导致:

    unlist(unname(DF[c("Num1","Num2")]))
    

    unlist 调用更改了数据的类别。正如帮助页面所说:

     The output type is determined from the highest type of the
     components in the hierarchy NULL < raw < logical < integer < real
     < complex < character < list < expression, after coercion of
     pairlists to lists.
    

    【讨论】:

    • 我们是说bit64应该实现unlist.integer64吗?
    • @Corone 不,我不这么认为。 unlist 转换其参数,因为它确实处理了它们不属于同一类的情况。例如unlist(list(1,"a",TRUE))。我不知道解决方案是什么。也许,在melt中,检查所有度量变量是否属于同一类,在这种情况下不要调用unlist
    • reshape 使用 rbind 将度量变量放在一起。 rbind.integer64 在 bit64 中实现。但即使在那里,您也可能会遇到变量类型更多的情况。最终,所有内容都需要转换为一种类型,这可能始终是最通用的数字。
    • @juba 可以很容易地请求 unlist 在 integer64 上工作 - 所以“不要使用 unlist”并不是真正的修复
    • @JanvanderLaan 但在这种情况下,unlist 中的唯一类型是 integer64,所以当 unlist 强制转换为“最高”时,它仍然应该是 integer64?
    猜你喜欢
    • 1970-01-01
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 1970-01-01
    • 2016-12-21
    • 2016-10-19
    • 2023-03-13
    相关资源
    最近更新 更多