让我们假设以下数据集:
+---------------+-----------+---------------------+ | flightCarrier | saleTotal | daysBeforeDeparture | +---------------+-----------+---------------------+ | KL | 477.99 | 0 | | AF | 457.99 | 0 | | SQ | 556.31 | 0 | +---------------+-----------+---------------------+
我想做的是以下内容:
工单 :
到目前为止我尝试了什么:
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
这没有成功并打印出“逻辑(0)”所以我猜没有结果。 我尝试了许多方法,使用lapply,mapply,但似乎所有人都比较静态数字而不是之前的行。
我从申请中得到的是,每一个X都有一行“迭代”。这就是为什么我试图比较X&gt; A而A是具有所有saleTotal值的整个矢量。因此,迭代每一个。
预期输出 业务输出:“价格比XY其他价格便宜”
我想这是避免使用大型矩阵并尽可能降低内存的最佳方法 有没有办法直接“nrow()”结果而不是先创建矩阵/列表?
+-----------+-------------+ | saleTotal | cheaperThan | +-----------+-------------+ | 477.99 | 1 | | 457.99 | 2 | | 556.31 | 0 | +-----------+-------------+
知道怎么做吗?性能怎么样,我有100000多行?
编辑:预期输出(单向)
答案 0 :(得分: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
值大于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
或者,如果你只想要一个逻辑矩阵:
res > 1
# [,1] [,2] [,3]
#[1,] FALSE TRUE FALSE
#[2,] FALSE FALSE FALSE
#[3,] TRUE TRUE FALSE
答案 1 :(得分:5)
请参阅最后关于效率的说明
根据您的预期输出,您可以迭代每个值并计算(TRUE
值的总和)此值比其他所有值便宜多少时间,并将列表返回到&#39;对&#39;计数值:
sapply(data[,2],function(x) {
list(x, sum(x < data[,2]))
})
以长格式提供:
[,1] [,2] [,3]
[1,] 477.99 457.99 556.31
[2,] 1 2 0
如果您只想在现有数据集中添加一列,则应执行以下操作:
data$cheaperThan <- sapply(data[,2],function(x) sum(x < data[,2]))
使用的数据:
> 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
@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