Aga*_*Aga 5 indexing for-loop r function
我创建了函数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)
}
Run Code Online (Sandbox Code Playgroud)
调用函数后dystryb我得到了这个:
> x<-c(1,2,3,4,5,6,7)
> dystryb(x)
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[51] 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[101] 1
Run Code Online (Sandbox Code Playgroud)
为什么这个函数不适用于参数30和59?当然,它不是要创建一个函数,它使"1"的向量,但我想说清楚问题出在哪里.
根本原因是数值精度。有关 R 相关的讨论,请参阅此SO 帖子。@Dirk-eddelbuettel 包含的链接提供了 R 的背景以及涵盖一般计算中的数值精度的最相关论文之一。这篇文章提供了与此问题背后的计算机科学相关的 SO 的更详细的一般答案。
为了表明根本原因是数值精度,请考虑您创建的序列。首先,默认打印出序列。
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
Run Code Online (Sandbox Code Playgroud)
一切看起来都不错。现在,打印出您的序列,告诉 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
Run Code Online (Sandbox Code Playgroud)
您会看到“30”存储的值是 29.999999999999996,“59”存储的值是 58.999999999999993。现在,如果我们将此序列转换为整数,我们将得到以下输出。
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
Run Code Online (Sandbox Code Playgroud)
此强制转换函数将 29.999999999999996 转换为 29,将 58.999999999999993 转换为 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
Run Code Online (Sandbox Code Playgroud)
round解决您的特定问题的一种解决方案是在将序列转换为整数之前使用。
identical(1:101, as.integer(round(seq(0,1, by = 0.01) * 100 + 1)))
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
71 次 |
| 最近记录: |