将data.table中的字符列转换为bigz整数

时间:2018-10-09 08:46:19

标签: r data.table gmp

我正在使用一个data.table,该fread是使用data.table从.txt文件中读取的。 integer包含一些bigz列以及一列非常大的整数,我打算将它们存储为fread。但是,如果我打算保留所有数字(并且我愿意),character只会以#Something to the effect of (run not needed): #fread(file = FILENAME.txt, header=TRUE, colClasses = c(rep("integer", 10), "character"), data.table = TRUE) 的形式读取大整数。

character

此外,我正在处理相当大的数据集。我的主要问题是将data.table中的bigz列转换为 data.table列,而无需创建新对象。

这是一个演示我的问题的玩具示例。首先,我知道bigz 可以有library(gmp) library(data.table) exa = as.bigz(2)^80 #A very large number cha = as.character(exa) #The same number in character form (good = data.table(nums = 1:3, lets = letters[1:3], bigs = rep(exa, 3))) str(good) #Notice "bigs" is type bigz (and raw?) 个列- IF ,它们是在新对象中引入的。

character

但是,如果要将bigz列即时转换为numeric列,则会导致错误。这些转换方法中的语法“有效”。如果numsas.bigz替换,则as.character (bad = data.table(nums = 1:3, lets = letters[1:3], bigs = rep(cha, 3))) str(bad) #Method 1 bad[,bigs:=as.bigz(bigs)] #Method 2 (re-create data.table first) bad = data.table(nums = 1:3, lets = letters[1:3], bigs = rep(cha, 3)) set(bad, j="bigs", value = as.bigz(bad$bigs)) 列。

bigz

以下错误。看来问题出在raw整数存储为exa,尽管我不确定'64'的来源-Warning messages: 1: In `[.data.table`(bad, , `:=`(bigs, as.bigz(bigs))) : Supplied 64 items to be assigned to 3 items of column 'bigs' (61 unused) 2: In `[.data.table`(bad, , `:=`(bigs, as.bigz(bigs))) : Coerced 'raw' RHS to 'character' to match the column's type. Either change the target column ['bigs'] to 'raw' first (by creating a new 'raw' vector length 3 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'character' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please. 有24位数字。

(bad = data.table(nums = 1:3, lets = letters[1:3], bigs = rep(cha, 3)))
meh = data.table(as.data.frame(bad)[,-3], bigs = as.bigz(bad$bigs))
rm(bad)
str(meh)
identical(good, meh)          #Well, at least this works

我现在有一个解决方法,但是它需要创建一个新对象(并删除旧对象)。

fread

我认为,在以下情况下,这种情况可以解决:

  1. bigz可以读取data.table个整数,或者
  2. 有一种无需创建新对象即可更改列类型的方法。

诚然,我是<fetch> <entity name="activitypointer" > <attribute name="activityid" /> <attribute name="regardingobjectid" /> <attribute name="subject" /> <attribute name="regardingobjecttypecode" /> <filter type="and" > <condition attribute="isregularactivity" operator="eq" value="1" /> <filter type="or" > <condition entityname="accountparty" attribute="accountid" operator="eq-or-under" value="5D8E9289-7F86-E811-910D-0050568B95ED" /> <condition entityname="contactparty" attribute="contactid" operator="eq-or-under" value="5D8E9289-7F86-E811-910D-0050568B95ED" /> </filter> </filter> <link-entity name="activityparty" from="activityid" to="activityid" link-type="outer" alias="activityparty" > <link-entity name="account" from="accountid" to="partyid" link-type="outer" alias="accountparty" /> <link-entity name="contact" from="contactid" to="partyid" link-type="outer" alias="contactparty" > <link-entity name="account" from="accountid" to="parentcustomerid" link-type="outer" alias="contactaccount" /> </link-entity> </link-entity> 的新手。预先感谢!

1 个答案:

答案 0 :(得分:1)

使用这些bigq数字似乎很麻烦。此外,似乎它们不能作为data.table中的唯一列。

我能找到的唯一解决方法是声明一个新的data.table,这是您已经完成的工作,只有这样才能更简洁地完成,而无需创建新对象。

library(gmp)
library(data.table)

exa = as.bigz(2)^80          #A very large number          
cha = as.character(exa)
bad = data.table(nums = 1:3, lets = letters[1:3], bigs = rep(cha, 3))
bad = data.table(bad,bigsN = as.bigz(bad$bigs))
str(bad)

但是,在没有相同问题的情况下,无法在data.table内部操纵这些列。

bad$bigsN = bad$bigsN*2
## Error in `[<-.data.table`(x, j = name, value = value) : 
##   Unsupported type 'raw'
## In addition: Warning message:
## In `[<-.data.table`(x, j = name, value = value) :
##   Supplied 64 items to be assigned to 3 items of column 'bigsN' (61 unused)

我能想到的最好的解决方案就是简单地将这些对象作为data.table的单独向量。

as.list

另一种解决方案是将bigz嵌入列表中。

library(gmp)
library(data.table)

exa = as.bigz(2)^80          #A very large number          
cha = as.character(exa)
bad = data.table(nums = 1:3, lets = letters[1:3], bigs = rep(cha, 3))
bad = bad[,bigs := as.list(as.bigz(bad$bigs))]

这使R可以更好地处理元素的位置,并且在创建阶段可以提高内存效率。不利的一面是每个元素都是一个长度为1的bigz向量,因此每个元素包含4个冗余字节的数据。它也仍然不能以向量化的方式用于算术。

 bad$bigs = bad$bigs * 2
## Error in bad$bigs * 2 : non-numeric argument to binary operator
 bad$bigs[[2]] = bad$bigs[[2]] * 2
 bad$bigs
## [[1]]
## Big Integer ('bigz') :
## [1] 1208925819614629174706176
## 
## [[2]]
## Big Integer ('bigz') :
## [1] 2417851639229258349412352
## 
## [[3]]
## Big Integer ('bigz') :
## [1] 1208925819614629174706176

实际上,似乎不可能以一种高级化的方式来完成它,包括对其进行排序甚至将其转换回bigz向量。