r - 在不使用循环的情况下在df列中查找一个值以上且小于一个值的值的数目

标签 r

考虑以下:

df <- data.frame(X = c(5000, 6000, 5500, 5000, 5300))

count_above <- function(vector)
{
  counts <- vector()
  counts[1] <- 0
  for (i in 2:length(vector))
  {
    temp <- vector[1:i]
    counts <- c(counts, sum(temp < vector[i]))
  }
  return(counts)
}

这给了我正确的输出:
count_above(df$X)
[1] 0 1 1 0 2

例如,这里的(列)向量是
5000
6000
5500
5000
5300

在最顶部的5000上,没有任何值。因此,这给出了0的值。

6000上方有一个值,小于6000:5000。因此,这给出了1的值。

5500上方有两个值,其中一个小于5500,因此它给出了1值,依此类推。

有什么办法可以不用循环就将其写出来?

最佳答案

另一种方法,与爱潮的解决方案非常相似(但略短一些)

X <- c(5000, 6000, 5500, 5000, 5300)
indices <- 1:length(X)
count_above <- colSums(outer(X, X, "<") & outer(indices, indices, "<"))
## [1] 0 1 1 0 2

编辑(性能):也许我的想法被选择为可接受的答案,因为它是简短且不言自明的代码-但请小心在大向量上使用它!这是这里建议的所有解决方案中最慢的方法!与德拉科多克所做的类似,我也进行了微基准测试。但是我使用了一个随机生成的3000个值的向量来获得更长的运行时间:
count_above_loop <- function(v)
{
  counts <- integer(length = length(v))
  counts[1] <- 0
  for (i in 2:length(v))
  {
    counts[i] <- sum(v[1:(i-1)] < v[i])
  }
  return(counts)
}

count_above_outer <- function(X) {
  indices <- 1:length(X)
  colSums(outer(X, X, "<") & outer(indices, indices, "<"))
}

count_above_apply <- function(X) {
  sapply(seq_len(length(X)), function(i) sum(X[i:1] < X[i]))
}

X <- runif(3000)

microbenchmark::microbenchmark(count_above_loop(X), 
                               count_above_apply(X),
                               count_above_outer(X), times = 10)

Unit: milliseconds
                 expr       min        lq      mean    median        uq       max neval cld
  count_above_loop(X)  56.27923  58.17195  62.07571  60.08123  63.92010  77.31658    10  a 
 count_above_apply(X)  54.41776  55.07511  57.12006  57.22372  58.61982  59.95037    10  a 
 count_above_outer(X) 121.12352 125.56072 132.45728 130.08141 137.08873 154.28419    10   b

我们看到,在大向量上且没有数据帧开销的情况下,套用方法比for循环要快一些。

我的外部产品方法花费的时间是原来的两倍以上。

因此,我建议使用for循环-它也易于阅读且速度更快。如果您想拥有可证明的正确代码,则可以考虑使用我的方法(因为这种单行代码非常接近问题的规范)

关于r - 在不使用循环的情况下在df列中查找一个值以上且小于一个值的值的数目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39558662/

相关文章:

r - 如何获得R脚本的运行时?

javascript - 在 R Shiny 中过滤 rhandsontable 中的行

R 包中的 rJava 类路径...适用于某些系统...不适用于其他系统

r - 使用基于行和列的另一个表中的值填充表

r - R 中的传单 : SetView based on range of latitude and longitude from dataset

通过在 purrr 中按元素求和来减少列表

r - 在没有插值的情况下计算 R 中的分位数 - 向上或向下舍入到实际值

r - 生成 N 个总和为 1 的均匀随机数

r - 无法从 R 中的 2 个整数除法获得所需的输出精度

r - 在 dplyr 管道中组合 ifelse 语句变异和序列