【问题标题】:Counting values to get to a specified column share threshold in R计数值以达到 R 中指定的列共享阈值
【发布时间】:2018-05-15 01:23:22
【问题描述】:

我将以下数据存储在列表中。我随后对 df1 和 df2 中的每一列进行排序,以找到每列前 5 个值的份额:

set.seed(12345)
df1 = data.frame(replicate(10,sample(0:500,1000,rep=TRUE)))
df2 = data.frame(replicate(10,sample(0:500,1000,rep=TRUE)))
list = list(df1, df2)

do.call(cbind,lapply(list, function(x) {
x1 <- x/colSums(x)[col(x)]
sapply(x1, function(y) sum(head(sort(y, decreasing = TRUE), 5)))}))

如何调整此代码以查找每一列的值计数从最大到最小排序以达到列总数的 80%(即,如果一列占 80.1%,那么该列的答案是 3)?

非常感谢!

【问题讨论】:

  • 我认为set.seed = 12345 没有做你认为它正在做的事情。 (请参阅?set.seed。)为了证明,请尝试两次set.seed=12345;runif(1);。 (底线:set.seed(12345)。)
  • nymuffin,下面的答案能解决你的问题吗?

标签: r apply


【解决方案1】:

分段(最后的解决方案):

col <- lst[[1]]$X1
( s80 <- 0.8*sum(col) )
# [1] 205634.4

我认为您想将最大的、第二大的等相加,并找出其中有多少(按降序排列)才能包含总和的 80%,即s80

所以首先我们排序:

head( sorted <- sort(col, decreasing=TRUE) ,n=10)
#  [1] 499 499 498 497 497 496 495 495 495 494

我们对它们进行累计:

head( cumsum(sorted) ,n=10)
#  [1]  499  998 1496 1993 2490 2986 3481 3976 4471 4965

以及那些是 gte s80 的(应该是一个索引并且超出它):

head(which( cumsum(sorted) >= s80 ))
# [1] 563 564 565 566 567 568

我们可以安全地抢到第一个。

do.call(rbind,
        lapply(lst, function(l) {
          sapply(l, function(col) {
            s80 <- 0.8*sum(col)
            sorted <- sort(col, decreasing=TRUE)
            which(cumsum(sorted) >= s80)[1]
          })
        })
        )
#       X1  X2  X3  X4  X5  X6  X7  X8  X9 X10
# [1,] 563 560 543 549 555 558 554 567 552 550
# [2,] 541 551 547 560 549 550 557 546 557 555

【讨论】:

    猜你喜欢
    • 2018-07-04
    • 1970-01-01
    • 1970-01-01
    • 2016-07-01
    • 2020-12-28
    • 2021-05-13
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多