将向量中的值与所有其他向量进行比较

s1x*_*s1x 3 r

我们假设以下数据集:

+---------------+-----------+---------------------+
| flightCarrier | saleTotal | daysBeforeDeparture |
+---------------+-----------+---------------------+
| KL            | 477.99    |                   0 |
| AF            | 457.99    |                   0 |
| SQ            | 556.31    |                   0 |
+---------------+-----------+---------------------+

我想做的是以下内容:

  1. 将列中的值与同一列中的所有其他值进行比较.
  2. saleTotal(1)小于saleTotal(2)和saleTotal(3)的值
  3. 如果是的话,多少钱?saleTotal(3)/ saleTotal(1)

工作单:

  • 477,99 <457,99(虚假)
  • 477,99 <556.31(真) - >(556.31/477.99)-1 = 1.16(增加16%)
  • 457.99 <477.99(真实) - > .....
  • 457.99 <556.31(true) - > .....
  • 556.31 <477.99(假)
  • 556.31 <457.99(假)

到目前为止我尝试过的:

cal <- apply(df_matrix[1:2,2], 1, function(x) {
  A <- x
  x <- x[-1]
  ifelse(x>A, 1, ifelse(x<A, 0, NA))
})
cal
Run Code Online (Sandbox Code Playgroud)

这没有成功并打印出"逻辑(0)"所以我猜没有结果.我尝试了许多方法,使用lapply,mapply但似乎所有人都比较静态数字而不是之前的行.

我所掌握的是,每个X都有一行"迭代".这就是为什么我试图比较X> A而A是具有所有saleTotal值的整个向量.因此,迭代每一个.


预期产出 业务产出:"价格比XY其他价格便宜"

我想这将是避免大型矩阵并尽可能降低内存的最佳方法.是否可能有一种方法直接"nrow()"结果而不是先创建矩阵/列表?

+-----------+-------------+
| saleTotal | cheaperThan |
+-----------+-------------+
| 477.99    |           1 |
| 457.99    |           2 |
| 556.31    |           0 |
+-----------+-------------+

知道怎么做吗?性能怎么样,我有100000多行?

编辑:预期输出(单向)

tal*_*lat 5

你可以?outer像这样使用:

outer(df$saleTotal, df$saleTotal, "/")
#          [,1]     [,2]      [,3]
#[1,] 1.0000000 1.043669 0.8592152
#[2,] 0.9581581 1.000000 0.8232640
#[3,] 1.1638528 1.214677 1.0000000
Run Code Online (Sandbox Code Playgroud)

值大于1表示增加,小于1的值表示减少,矩阵的对角线全部为1,因为它将每个值与自身进行比较.

当然,您可以将其修改为仅显示大于1的值,例如通过使用:

res <- outer(df$saleTotal, df$saleTotal, "/")
res * as.integer(res > 1)
#         [,1]     [,2] [,3]
#[1,] 0.000000 1.043669    0
#[2,] 0.000000 0.000000    0
#[3,] 1.163853 1.214677    0
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想要一个逻辑矩阵:

res > 1
#      [,1]  [,2]  [,3]
#[1,] FALSE  TRUE FALSE
#[2,] FALSE FALSE FALSE
#[3,]  TRUE  TRUE FALSE
Run Code Online (Sandbox Code Playgroud)

  • @ s1x如果必须将每个值与所有其他值进行比较,那么结果向量显然至少是'factorial(length(data [,'saleTotal']))`无论如何...... (4认同)

Ten*_*bai 5

最后请参阅关于效率的说明

使用您的预期输出,您可以迭代每个值并计算(总和TRUE值)此值比其他所有值更便宜的时间,并返回一个列表以将值与计数"配对":

sapply(data[,2],function(x) {
  list(x, sum(x < data[,2]))
})
Run Code Online (Sandbox Code Playgroud)

以长格式给出:

     [,1]   [,2]   [,3]  
[1,] 477.99 457.99 556.31
[2,] 1      2      0     
Run Code Online (Sandbox Code Playgroud)

如果您只想在现有数据集中添加列,则应执行以下操作:

data$cheaperThan <- sapply(data[,2],function(x) sum(x < data[,2])) 
Run Code Online (Sandbox Code Playgroud)

使用的数据:

> system.time(sapply(large,function(x) sum(x < large)))
utilisateur     système      écoulé 
       1.08        0.22        1.30 
> system.time(length(large) - findInterval(large,sort(large)))
utilisateur     système      écoulé 
       0.01        0.00        0.01 
Run Code Online (Sandbox Code Playgroud)

@alexis_laz解决方案,如果确实真的更有效:

> set.seed(123)
> test <- runif(50000)*100
> identical(sapply(test,function(x) sum(x < test)), (length(test) - findInterval(test,sort(test))))
[1] TRUE
> system.time(sapply(test,function(x) sum(x < test)))
utilisateur     système      écoulé 
      13.64        1.24       14.96 
> system.time(length(test) - findInterval(test,sort(test)))
utilisateur     système      écoulé 
       0.01        0.00        0.02
Run Code Online (Sandbox Code Playgroud)