首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R,bit64,data.table中行均值和标准差的计算问题

R,bit64,data.table中行均值和标准差的计算问题
EN

Stack Overflow用户
提问于 2016-09-24 08:57:55
回答 1查看 801关注 0票数 3

我试着用更大的数字,超过2^32。虽然我也在使用data.table和fread,但我不认为这个问题与它们有关。我可以打开和关闭他们的症状,而不改变data.table或使用氟得。我的症状是,当我期望一个正指数1e+3到1e+17时,我得到的平均值是4.1e-302。

在使用bit64包和与integer64相关的函数时,问题始终会出现。在“常规大小的数据和R”中,事情对我有用,但我没有在这个包中正确地表达东西。请参阅下面的代码和数据。

我是在一个MacBook Pro,16 i7,i7(更新)。

我已经重新启动了我的R会话并清除了工作区,但问题始终存在。

请告知,我很感谢您的意见。我认为它必须使用库,bit64。

我看过的链接包括bit64文档

fread()内存泄漏引起的类似症状的问题,但我认为我消除了

这是我的输入数据

代码语言:javascript
复制
var1,var2,var3,var4,var5,var6,expected_row_mean,expected_row_stddev
1000 ,993 ,987 ,1005 ,986 ,1003 ,996 ,8 
100000 ,101040 ,97901 ,100318 ,96914 ,97451 ,98937 ,1722 
10000000 ,9972997 ,9602778 ,9160554 ,8843583 ,8688500 ,9378069 ,565637 
1000000000 ,1013849241 ,973896894 ,990440721 ,1030267777 ,1032689982 ,1006857436 ,23096234 
100000000000 ,103171209097 ,103660949260 ,102360301140 ,103662297222 ,106399064194 ,103208970152 ,2078732545 
10000000000000 ,9557954451905 ,9241065464713 ,9357562691674 ,9376495364909 ,9014072235909 ,9424525034852 ,334034298683 
1000000000000000 ,985333546044881 ,994067361457872 ,1034392968759970 ,1057553099903410 ,1018695335152490 ,1015007051886440 ,27363415718203 
100000000000000000 ,98733768902499600 ,103316759127969000 ,108062824583319000 ,111332326225036000 ,108671041505404000 ,105019453390705000 ,5100048567944390 

我的代码,使用这个示例数据

代码语言:javascript
复制
# file: problem_bit64.R
# OBJECTIVE: Using larger numbers, I want to calculate a row mean and row standard deviation
# ERROR:  I don't know what I am doing wrong to get such errors, seems bit64 related
# PRIORITY: BLOCKED (do this in Python instead?)
# reported Sat 9/24/2016 by Greg

# sample data:
# each row is 100 times larger on average, for 8 rows, starting with 1,000
# for the vars within a row, there is 10% uniform random variation.  B2 = ROUND(A2+A2*0.1*(RAND()-0.5),0)    

# Install development version of data.table --> for fwrite()
install.packages("data.table", repos = "https://Rdatatable.github.io/data.table", type = "source")
require(data.table)
require(bit64)
.Machine$integer.max   # 2147483647     Is this an issue ?
.Machine$double.xmax   # 1.797693e+308  I assume not

# -------------------------------------------------------------------
# ---- read in and basic info that works
csv_in <- "problem_bit64.csv"
dt <- fread( csv_in )
dim(dt)                # 6 8
lapply(dt, class)      # "integer64" for all 8
names(dt)  # "var1" "var2"  "var3"  "var4"  "var5" "var6" "expected_row_mean" "expected_row_stddev"
dtin <- dt[, 1:6, with=FALSE]  # just save the 6 input columns

..。现在问题开始了

代码语言:javascript
复制
# -------------------------------------------------------------------
# ---- CALCULATION PROBLEMS START HERE
# ---- for each row, I want to calculate the mean and standard deviation
a <- apply(dtin, 1, mean.integer64); a   # get 8 values like 4.9e-321
b <- apply(dtin, 2, mean.integer64); b   # get 6 values like 8.0e-308

# ---- try secondary variations that do not work
c <- apply(dtin, 1, mean); c             # get 8 values like 4.9e-321
c <- apply(dtin, 1, mean.integer64); c   # same result
c <- apply(dtin, 1, function(x) mean(x));   c          # same
c <- apply(dtin, 1, function(x) sum(x)/length(x));  c  # same results as mean(x)

##### I don't see any sd.integer64       # FEATURE REQUEST, Z-TRANSFORM IS COMMON
c <- apply(dtin, 1, function(x) sd(x));   c          # unrealistic values - see expected

常规数据的正则大小R,仍然使用用fread()读取到data.table()中的数据- WORKS

代码语言:javascript
复制
# -------------------------------------------------------------------
# ---- delete big numbers, and try regular stuff - WHICH WORKS
dtin2 <- dtin[ 1:3, ]    # just up to about 10 million (SAME DATA, SAME FREAD, SAME DATA.TABLE)
dtin2[ , var1 := as.integer(var1) ]  # I know there are fancier ways to do this
dtin2[ , var2 := as.integer(var2) ]  # but I want things to work before getting fancy.
dtin2[ , var3 := as.integer(var3) ]
dtin2[ , var4 := as.integer(var4) ]
dtin2[ , var5 := as.integer(var5) ]
dtin2[ , var6 := as.integer(var6) ]
lapply( dtin2, class )   # validation

c <- apply(dtin2, 1, mean); c   # get 3 row values AS EXPECTED (matching expected columns)
c <- apply(dtin2, 1, function(x) mean(x));   c          # CORRECT
c <- apply(dtin2, 1, function(x) sum(x)/length(x));  c  # same results as mean(x)

c <- apply(dtin2, 1, sd); c             # get 3 row values AS EXPECTED (matching expected columns)
c <- apply(dtin2, 1, function(x) sd(x));   c          # CORRECT
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-25 12:04:46

作为对大多数读者的简短和第一条建议:除非您有特定的理由使用64位整数,否则请使用“double”而不是“integer64”。'double‘是一个R内部数据类型,而'integer64’是一个包扩展数据类型,它表示为一个具有类属性‘integer 64’的'double‘向量,也就是说,每个元素64位都被知道这个类的代码解释为64位整数。不幸的是,许多核心R函数不知道“整数64”,这很容易导致错误的结果。因此,胁迫成“双重”

代码语言:javascript
复制
dtind <- dtin
for (i in seq_along(dtind))
  dtind[[i]] <- as.double(dtind[[i]])
b <- apply(dtind, 1, mean)

会给出一些预期的结果

代码语言:javascript
复制
> b
[1] 9.956667e+02 9.893733e+04 9.378069e+06 1.006857e+09 1.032090e+11 9.424525e+12 1.015007e+15 1.050195e+17

虽然与你所期望的不完全一样,但也没有看到四舍五入的差异。

代码语言:javascript
复制
> b - dt$expected_row_mean
integer64
[1] -1   0    -1   -1   0    -1   -3   -392

也不去看那些毫无意义的差异

代码语言:javascript
复制
> b - as.double(dt$expected_row_mean)
[1]   -0.3333333    0.3333333   -0.3333333   -0.1666666    0.1666718 -0.3339844   -2.8750000 -384.0000000
Warnmeldung:
In as.double.integer64(dt$expected_row_mean) :
  integer precision lost while converting to double

好的,假设你真的想要integer64,因为你的最大数字超过了2^52倍的整数精度。然后,您的问题首先是“应用”不知道integer64,实际上破坏了“integer64”类属性:

代码语言:javascript
复制
> apply(dtin, 1, is.integer64)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

它实际上销毁了“integer64”类属性两次,一次是在准备输入时,一次是在后置处理输出时。我们可以通过

代码语言:javascript
复制
c <- apply(dtin, 1, function(x){
  oldClass(x) <- "integer64"  # fix 
  mean(x) # note that this dispatches to mean.integer64
})
oldClass(c) <- "integer64"  # fix again

现在看来结果是合理的

代码语言:javascript
复制
> c
integer64
[1] 995                98937              9378068            1006857435         103208970152       9424525034851      1015007051886437   105019453390704600

但仍然不是你所期望的

代码语言:javascript
复制
> c - dt$expected_row_mean
integer64
[1] -1   0    -1   -1   0    -1   -3   -400

小差(-1)是由于四舍五入造成的,因为浮动平均数。

代码语言:javascript
复制
> b[1]
[1] 995.6667

你假设

代码语言:javascript
复制
> dt$expected_row_mean[1]
integer64
[1] 996

而mean.integer64胁迫(截断)到integer64。然而,mean.integer64的这种行为是有争议的,至少是一致的:

代码语言:javascript
复制
x <- seq(0, 1, 0.25)
> data.frame(x=x, y=as.integer64(0) + x)
     x y
1 0.00 0
2 0.25 0
3 0.50 0
4 0.75 0
5 1.00 1
> mean(as.integer64(0:1))
integer64
[1] 0

四舍五入的主题清楚地表明,实现sd.integer64将是更有争议的。它应该返回integer64还是双倍?

关于更大的差异,还不清楚您的期望的基本原理是什么:取表的第七行并减去其最小值。

代码语言:javascript
复制
x <- (unlist(dtin[7,]))
oldClass(x) <- "integer64"
y <- min(x)
z <- as.double(x - y)

给出“双”精确处理整数的范围内的数字。

代码语言:javascript
复制
> log2(z)
[1] 43.73759     -Inf 42.98975 45.47960 46.03745 44.92326

平均这些值并与你的预期进行比较仍然会给出一个用四舍五入解释的差异。

代码语言:javascript
复制
> mean(z) - as.double(dt$expected_row_mean[7] - y)
[1] -2.832031
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39674503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档