将data.table列类更改为integer64,分别为double

时间:2018-12-14 22:20:21

标签: r data.table

给出data.table dt:

dt <- structure(list(V1 = c("1544018118438041139", "1544018118466235879", 
"1544018118586849680", "1544018118601169211", "1544018118612947335", 
"1544018118614422179"), V2 = c("162", "162", "161.05167", "158.01309", 
"157", "157"), V3 = c("38", "38", "36.051697", "33.01306", "32", 
"32"), V4 = c("0.023529414", "0.025490198", "0.023529414", "0.027450982", 
"0.03137255", "0.03137255"), V5 = c("1", "1", "1", "1", "1", 
"1"), V6 = c("2131230815", "2131230815", "2131230815", "2131230815", 
"2131230815", "2131230815"), V7 = c("1", "0", "0", "0", "0", 
"-1")), class = c("data.table", "data.frame"), row.names = c(NA, 
-6L), .internal.selfref = <pointer: 0x2715f60>)

我希望第一列为bit64::as.integer64(),其余列为as.numeric()

我正在尝试这样做:

dt <- dt[ ,V1 := bit64::as.integer64(V1)]

dt[, lapply(.SD, as.numeric), .SDcols = -c("V1")]

但是它似乎并没有满足我的要求,请建议如何将特定列更改为A类(integer64),将其余列更改为另一个B类(例如as.numeric())?

3 个答案:

答案 0 :(得分:3)

从以上评论看来,您希望能够一步一步完成所有操作,而不是将第一个转换为integer64,然后将其余转换为double。一种执行此操作的方法是:

dt[, names(dt) := Map(function(fun, x) fun(x), rep(list(bit64::as.integer64, as.numeric), times = c(1,length(.SD) - 1)), .SD), .SDcols = names(dt)]

Map函数一起迭代您的输入。也就是说,它将第一个和第二个向量的第一个元素作为参数传递给我们的函数。然后,它接受两个向量的第二个元素,并将它们传递给函数。

在我们的Map电话中,我们有:

  • 要应用的主要功能。这是一个匿名函数,需要两个折点(1)fun和(2)x。我们函数的结果是将fun应用于xfun(x)的结果。举一个具体的例子:

    myfun <- function(fun, x){
      fun(x)
    }
    res<-myfun(as.numeric, c("1","1")); class(res)
    
  • 要传递给我们的主要功能的功能列表。这些将在我们的主要功能中用作fun。在这种情况下,其list(as.integer64, as.numeric, as.numeric,...)

  • 要传递给我们的主函数的向量列表。这些将在我们的主要功能中用作x。在这种情况下,我们dt的每一列。

一种快速而又肮脏的视觉辅助工具(假设custom_function有两个参数):

enter image description here

答案 1 :(得分:2)

在我看来,自该纪元以来,您有一个{。{1}}纳秒时间戳的data.table对象。我在工作中使用相同的代表高分辨率时间戳。

好消息是data.table支持此操作-依靠我们的软件包nanotime,该软件包本身将bit64用作integer64类型。但是,我创建时间戳的方式不同,通常与检索数据的已编译代码不同。

我在Rcpp Gallery中的this post 中对此进行了详细描述。因此,有些好消息:可以做到。一条坏消息:我认为您无法按照自己的方式进行操作,因为我们只能通过integer64进行操作,该精度只有16位小数,而不是19位。但是,也许我错过了窍门,所以如果存在更简单的解决方案我会全神贯注。 (而且我一直忘了是否存在“通过字符串方法解析int64”。我从来没有走过那条路,因为您无法大规模进行此操作-我也处理相当大的数据集。)

答案 2 :(得分:1)

谢谢大家,@ dirk_eddelbuettel我设法做到了:

1)加载所有JSON文件(以我为例)并使用

bigint_as_char=TRUE

fromJSON命令中。

2)现在,您有了一个大表,其中所有列都是字符。

3)将时间戳列转换为bit64::as.integer64()-您会得到我想要的数字。

4)将其余的转换为所需的类型。

5)当我想执行计算时,例如timestamp - lag(timestamp),我将lag_timestamp = lag(timestamp)(带有dplyr::mutate)添加为新列,并添加diff_column =将其存储{ {1}}

6)您几乎完成了-新的diff列将我想要的值存储为字符串/字符,现在您可以在需要时将其转换为as.character()或应用as.numeric()来处理不相关的值

7)就是这样,它对我来说非常完美,并且不会使R Studio崩溃。

在应用我的解决方案之前,R Studio崩溃了。