sapply() 以定义的小数向量作为参数,以 seq() 作为参数给出不同的结果
sapply() with defined vector of decimals as argument and with seq() as argument giving different results
我正在尝试获取数据框中一列中超过特定阈值的值的数量,十进制值范围从 0 到 1。为此,我使用 sapply 迭代列表阈值。当我提供定义的阈值向量时,sapply 工作正常但是当我使用 seq() 定义阈值时,我得到奇怪的结果(重复)并且结果不匹配。这只发生在小数上而不是整数上。
t <- data.frame(replicate(10,sample((0:10)/10,1000,rep=TRUE)))
l <- c()
l <- sapply(c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9), function(x){
nrow(t[t[,"X1"]>=x,]);
});
l2 <- c()
l2 <- sapply(seq(0, 0.9, 0.1), function(x){
nrow(t[t[,"X1"]>=x,]);
});
print(l)
print(l2)
输出:
> print(l)
[1] 1000 909 811 723 626 530 443 365 275 187
> print(l2)
[1] 1000 909 811 626 626 530 365 275 275 187
当使用整数和整数阈值执行相同的代码时,l 和 l2 完美匹配。
整数代码:
t <- data.frame(replicate(10,sample(0:10,1000,rep=TRUE)))
l <- c()
l <- sapply(c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), function(x){
nrow(t[t[,"X1"]>=x,]);
});
l2 <- c()
l2 <- sapply(seq(0, 9, 1), function(x){
nrow(t[t[,"X1"]>=x,]);
});
print(l)
print(l2)
输出:
> print(l)
[1] 1000 915 816 729 643 555 468 367 270 188
> print(l2)
[1] 1000 915 816 729 643 555 468 367 270 188
我不确定我是否遗漏了一些非常基本的东西或犯了错误。
谢谢。
这是因为 seq()
没有产生您期望的精确小数值:
> seq(0, 0.9, 0.1)[4] == 0.3
[1] FALSE
使用 all.equal
计算与精确小数的微小偏差(浮点错误)可以恢复 "equality"
> all.equal(seq(0, 0.9, 0.1)[4], 0.3)
[1] TRUE
整数版本不受相同浮点错误的影响,因此您会看到两种方法的一致行为。
的实例
解决此问题:
grt_or_near <- function (x, y, tol = .Machine$double.eps^0.5)
{
(x > y) | (abs(x - y) < tol)
}
t <- data.frame(replicate(10,sample((0:10)/10,1000,rep=TRUE)))
l <- sapply(c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9), function(x){
nrow(t[grt_or_near(t[,"X1"],x),])
})
l2 <- sapply(seq(0, 0.9, 0.1), function(x){
nrow(t[grt_or_near(t[,"X1"],x),])
})
l
# [1] 1000 924 830 759 664 570 480 374 290 186
l2
# [1] 1000 924 830 759 664 570 480 374 290 186
我正在尝试获取数据框中一列中超过特定阈值的值的数量,十进制值范围从 0 到 1。为此,我使用 sapply 迭代列表阈值。当我提供定义的阈值向量时,sapply 工作正常但是当我使用 seq() 定义阈值时,我得到奇怪的结果(重复)并且结果不匹配。这只发生在小数上而不是整数上。
t <- data.frame(replicate(10,sample((0:10)/10,1000,rep=TRUE)))
l <- c()
l <- sapply(c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9), function(x){
nrow(t[t[,"X1"]>=x,]);
});
l2 <- c()
l2 <- sapply(seq(0, 0.9, 0.1), function(x){
nrow(t[t[,"X1"]>=x,]);
});
print(l)
print(l2)
输出:
> print(l)
[1] 1000 909 811 723 626 530 443 365 275 187
> print(l2)
[1] 1000 909 811 626 626 530 365 275 275 187
当使用整数和整数阈值执行相同的代码时,l 和 l2 完美匹配。
整数代码:
t <- data.frame(replicate(10,sample(0:10,1000,rep=TRUE)))
l <- c()
l <- sapply(c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), function(x){
nrow(t[t[,"X1"]>=x,]);
});
l2 <- c()
l2 <- sapply(seq(0, 9, 1), function(x){
nrow(t[t[,"X1"]>=x,]);
});
print(l)
print(l2)
输出:
> print(l)
[1] 1000 915 816 729 643 555 468 367 270 188
> print(l2)
[1] 1000 915 816 729 643 555 468 367 270 188
我不确定我是否遗漏了一些非常基本的东西或犯了错误。
谢谢。
这是因为 seq()
没有产生您期望的精确小数值:
> seq(0, 0.9, 0.1)[4] == 0.3
[1] FALSE
使用 all.equal
计算与精确小数的微小偏差(浮点错误)可以恢复 "equality"
> all.equal(seq(0, 0.9, 0.1)[4], 0.3)
[1] TRUE
整数版本不受相同浮点错误的影响,因此您会看到两种方法的一致行为。
的实例解决此问题:
grt_or_near <- function (x, y, tol = .Machine$double.eps^0.5)
{
(x > y) | (abs(x - y) < tol)
}
t <- data.frame(replicate(10,sample((0:10)/10,1000,rep=TRUE)))
l <- sapply(c(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9), function(x){
nrow(t[grt_or_near(t[,"X1"],x),])
})
l2 <- sapply(seq(0, 0.9, 0.1), function(x){
nrow(t[grt_or_near(t[,"X1"],x),])
})
l
# [1] 1000 924 830 759 664 570 480 374 290 186
l2
# [1] 1000 924 830 759 664 570 480 374 290 186