【问题标题】:R comparing unequal vectors with inequalityR比较不等向量和不等式
【发布时间】:2014-12-05 18:52:51
【问题描述】:

我有两个长度不等的单向量数据帧

aa<-data.frame(c(2,12,35))
bb<-data.frame(c(1,2,3,4,5,6,7,15,22,36))

对于 aa 中的每个观察值,我想计算 bb 小于 aa 的实例数

我的结果:

   bb<aa 
1   1
2   7
3   9

我已经能够通过创建一个函数和使用应用两种方式来做到这一点,但是我的数据集很大,我让一个运行一整夜没有结束。

我有什么:

fun1<-function(a,b){k<-colSums(b<a)
                    k<-k*.000058242}

system.time(replicate(5000,data.frame(apply(aa,1,fun1,b=bb))))
       user  system elapsed 
      3.813   0.011   3.883 

其次,

fun2<-function(a,b){k<-length(which(b<a))
                    k<-k*.000058242}

system.time(replicate(5000,data.frame(apply(aa,1,fun2,b=bb))))
   user  system elapsed 
  3.648   0.006   3.664 

第二个函数在我所有的测试中都稍微快一点,但我让第一个函数在 bb>1.7m 和 aa>160k 的数据集上运行了一整夜

我找到了this post,并尝试使用 with() 但似乎无法使其正常工作,还尝试了 for 循环但没有成功。

感谢任何帮助或指导。

谢谢!

【问题讨论】:

  • 它们必须是数据框吗?为什么不只是向量?你试过sapply(aa[[1]],function(x)sum(bb[[1]]&lt;x))吗?如果 aabb 非常向量,这将是更重要的。
  • 一个向量很好,我的初始数据在一个数据框中,但如果它可以在 2 个向量上完成,那就太好了。

标签: r for-loop vectorization apply inequality


【解决方案1】:
aa<-data.frame(c(2,12,35))
bb<-data.frame(c(1,2,3,4,5,6,7,15,22,36))
sapply(aa[[1]],function(x)sum(bb[[1]]<x))
# [1] 1 7 9

一些更现实的例子:

n  <- 1.6e3
bb <- sample(1:n,1.7e6,replace=T)
aa <- 1:n
system.time(sapply(aa,function(x)sum(bb<x)))
#    user  system elapsed 
#   14.63    2.23   16.87 

n  <- 1.6e4
bb <- sample(1:n,1.7e6,replace=T)
aa <- 1:n
system.time(sapply(aa,function(x)sum(bb<x)))
#    user  system elapsed 
#  148.77   18.11  167.26 

所以使用length(aa) = 1.6e4 这大约需要 2.5 分钟(在我的系统上),并且过程缩放为 O(length(aa)) - 这并不奇怪。因此,对于您的完整数据集,它应该在大约 25 分钟内运行。还是有点慢。也许其他人会想出更好的方法。

【讨论】:

  • 成功了!在我的机器上大约 30 分钟。为什么你有更好的方法?我是 R 新手,正在努力从错误中吸取教训!谢谢
  • 查看用于分析代码的Rprof(...)summaryRprof(...)
  • 有趣。我收到一个错误 Error: cannot allocate vector of size 10.1 Gb 这以前从未发生过
【解决方案2】:

我原来的帖子我找了多少次bb

所以在我的例子中

aa<-data.frame(c(2,12,35))
bb<-data.frame(c(1,2,3,4,5,6,7,15,22,36))

 x<-ecdf(bb[,1])

 x(2)

[1] 0.2

 x(12)

[1] 0.7

 x(35)

[1] 0.9

要在我原来的帖子中得到答案,我需要乘以 bb 中的数据点数,在这种情况下为 10。虽然第一个不一样,因为在我原来的帖子中我说过 bb

我正在处理包含超过 100 万个数据点的陆地高程和水位高程的大型数据集,但最终我创建了一条淹没曲线。我想知道在给定超标概率的情况下,有多少土地会被淹没。

因此,对所有 100 万个数据点使用上述 ecdf() 函数仍然很耗时,但我意识到我不需要所有数据点就足以创建我的曲线。

因此,我将 ecdf() 函数应用于整个土地数据集,然后创建了一个水的高程序列,该序列大到足以创建我需要的曲线,但又小到可以快速计算。

land_elevation <- data.frame(rnorm(1e6))
water_elevation<- data.frame(rnorm(1e6))

cdf_land<- ecdf(land_elevation[,1])

elevation_seq <- seq(from = min(water_elevation[,1]), to = max(water_elevation[,1]), length.out = 1000)

land                  <- sapply(elevation_seq, cdf_land)

我的结果是一样的,但速度要快得多。

【讨论】:

  • 你看过data.table吗?我只是在 0.32 秒内完成了
  • 不确定你的意思。 data.table 有什么用?应用 cdf_land 函数?
  • 不,只是数据表。我跑了as.data.table(land_elevation)[, vapply(.I, "&gt;", water_elevation[[1]], 1)],速度超级快
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 2023-03-08
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多