Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
r中的索引,某些点的问题_R_Function_For Loop_Indexing - Fatal编程技术网

r中的索引,某些点的问题

r中的索引,某些点的问题,r,function,for-loop,indexing,R,Function,For Loop,Indexing,我创建了函数dyst和dystryb: dyst<- function(t,x) { f<-1 return(f) } dystryb<- function(x) { x<-sort(x) s<- numeric(101) u<-seq(0,1, by = 0.01) for (t in u) { s[t*100+1]<-dyst(t,x) } return(s) } 为什么这个函数对参数30和59不起作用?

我创建了函数
dyst
dystryb

dyst<- function(t,x)
{
  f<-1
  return(f)
}
dystryb<- function(x)
{
  x<-sort(x)
  s<- numeric(101)
  u<-seq(0,1, by = 0.01)
  for (t in u)
  {
    s[t*100+1]<-dyst(t,x)
  }
  return(s)
}

为什么这个函数对参数30和59不起作用?当然,这不是关于构造一个函数,它使向量为“1”,但我想说清楚,问题出在哪里。

根本原因是数值精度。有关R的讨论,请参见此。@Dirk-eddelbuettel包含的链接提供了R和一篇涉及一般计算中的数值精度的最相关论文的背景。提供了一个更详细的一般性答案,与本问题背后的计算机科学有关

<> P>为了说明根本原因是数值精度,考虑您创建的序列。首先,默认打印输出序列

print(seq(0,1, by = 0.01) * 100 + 1)
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
 [20]  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38
 [39]  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57
 [58]  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76
 [77]  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95
 [96]  96  97  98  99 100 101
一切看起来都很好。现在,打印出序列,告诉R显示16位数字

print(seq(0,1, by = 0.01) * 100 + 1, digits=16)
  [1]   1.000000000000000   2.000000000000000   3.000000000000000
  [4]   4.000000000000000   5.000000000000000   6.000000000000000
                                  ...
 [25]  25.000000000000000  26.000000000000000  27.000000000000000
 [28]  28.000000000000000  29.000000000000004  29.999999999999996
 [31]  31.000000000000000  32.000000000000000  33.000000000000000
 [34]  34.000000000000000  35.000000000000000  36.000000000000000
 [37]  37.000000000000000  38.000000000000000  39.000000000000000
 [40]  40.000000000000000  41.000000000000000  42.000000000000000
 [43]  43.000000000000000  44.000000000000000  45.000000000000000
 [46]  46.000000000000000  47.000000000000000  48.000000000000000
 [49]  49.000000000000000  50.000000000000000  51.000000000000000
 [52]  52.000000000000000  53.000000000000000  54.000000000000000
 [55]  55.000000000000000  56.000000000000007  57.000000000000007
 [58]  58.000000000000007  58.999999999999993  60.000000000000000
                               ...
[100] 100.000000000000000 101.000000000000000
您可以看到,“30”存储的值为29.99999999996,“59”存储的值为58.99999999993。现在,如果我们将这个序列转换为整数,我们将得到以下输出

print(as.integer(seq(0,1, by = 0.01) * 100 + 1))
  [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
 [20]  20  21  22  23  24  25  26  27  28  29  29  31  32  33  34  35  36  37  38
 [39]  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57
 [58]  58  58  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76
 [77]  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95
 [96]  96  97  98  99 100 101
此强制函数将29.999999999996转换为29,将58.999999999993转换为58,基本上执行截断。因此,在您的代码中,第29和58个元素被引用了两次,而第30和59个元素根本没有被引用

在这种情况下,输出与使用
floor
功能相同

identical(trunc(seq(0,1, by = 0.01) * 100 + 1), floor(seq(0,1, by = 0.01) * 100 + 1))
[1] TRUE
解决特定问题的一种方法是在将序列强制转换为整数之前使用
舍入

identical(1:101, as.integer(round(seq(0,1, by = 0.01) * 100 + 1)))
[1] TRUE

下面显示了发生的情况,您将在位置15、29、,。。。因为浮点精度错误

which(seq(0,1, by = 0.01)*100+1 != 1:101)
# [1] 15 29 30 56 57 58 59

我相信这与0.3的内部存储方式有关。因为它是一个循环数,乘以100会使它有一点变化。大概只是一个想法这个解决方案真的很有帮助。我考虑过数字精度,但我不知道如何提高这个精度。多谢各位!当然,数字精度问题可能会以意想不到的方式出现。
which(seq(0,1, by = 0.01)*100+1 != 1:101)
# [1] 15 29 30 56 57 58 59