【问题标题】:Pick out top 50% of data in every column在每列中挑选出前 50% 的数据
【发布时间】:2016-08-23 21:51:39
【问题描述】:

假设这是我的矩阵“marx”,nrow=400 ncol=250。 我只想从每一列(不包括 NA)中选择一半的数据(前 50%)

          V272      V273       V274      V275       V276      V277
[1,] 0.2337847 0.2612946 0.41232797        NA 0.11931570 0.2543780
[2,] 0.3277191 0.3590431 0.06490879 0.2690663         NA 0.1632647
[3,]        NA 0.1536955 0.03604548 0.1361645         NA 0.2252554
[4,] 0.3483152 0.5342417 0.07404933        NA 0.14699876 0.2082977
[5,] 0.4213399 0.2511010 0.30502173 0.1189562 0.08962128 0.2919712
[6,] 0.1604953 0.2101048         NA        NA 0.01270747 0.2322928

我已尝试使用 sample=length (x)/2 和循环,但仍然无法正常工作。有人有什么想法吗?

【问题讨论】:

  • 您想从每一列中独立随机抽样吗?还是只有矩阵的前半部分?或者对每一列的数据进行排序并选择中位数以上的所有内容?你的数据结构是什么类?你说“矩阵”你称之为df,这意味着data.frame...
  • 如果您想保持数据完整(按行),一种选择是执行complete.cases(),然后取出剩余的行数。 df <- df[complete.cases(df), ]; df <- df[sample(1:nrow(df), n), ] 其中 n 是您想要的行数。
  • 我想对数据进行降序排序。然后从每列中选择一半的数字(不包括 NA)。哦,对不起,我的数据是矩阵形式的。
  • 按哪一列降序排列?或者,就像上面问的@Gregor,你想逐列而不关心它们之间的关系?完全不清楚你想要什么。
  • 我在上面提到过。将每一列按降序排序,是的,我忽略了它们之间的关系。希望清楚。

标签: r matrix filter time-series


【解决方案1】:

看看使用 head() 函数。

b <- data.frame(1:4, 2:8)
head(b, n = nrow(b/2))

这不会删除你的 NA,所以你可以这样做

head(b[!is.na(b[,1]),1], n = nrow(b)/2)

并迭代或使用应用函数。将 b[,1]),1] 中的 1 更改为您的列。您将有一个参差不齐的数组,因为您的 NA 散布在每一列中。

编辑:看到你的评论,你应该使用顺序,即:

apply(b, 2, function(x) head(x[order(x, decreasing = TRUE)], n = length(x)/2))

【讨论】:

  • 应用您的公式,我收到此错误消息 Error: length(n) == 1L is not TRUE
  • 用长度替换 nrow,并确保包含我错过的逗号: apply(b 2, function(x) head(x[order(x, reduction = TRUE)], n = length( x)/2)) 抱歉,双重更新,在调用 head 之前,您还需要使用顺序对矩阵进行子集化。
【解决方案2】:

我会这样做:

apply(x, 2, FUN = function(x) sort(x, decreasing = T)[1:floor(length(x)/2)])

演示:

set.seed(47)
x = matrix(rnorm(100), 10)
x[1, 3] = NA
x
#              [,1]        [,2]        [,3]          [,4]        [,5]       [,6]        [,7]       [,8]
#  [1,]  1.99469634 -0.92245624          NA  0.4836041107  0.06116275  0.9697466  0.03838225  1.2174872
#  [2,]  0.71114251  0.03960243  0.24914817  0.1443376363 -0.10856462  1.6756248  0.06893424  0.7314502
#  [3,]  0.18540528  0.49382018 -0.34041599 -1.2004406274 -0.15469524  1.9882438  1.74017016  1.1339939
#  [4,] -0.28176501 -1.82822917  0.41719084  0.8852306473  0.95048417 -0.9870583  1.30627664  2.1879180
#  [5,]  0.10877555  0.09147291 -0.32646679  0.8869350447 -0.48769640 -1.8300307 -0.14493417  0.2212036
#  [6,] -1.08573747  0.67077922 -0.89029402  0.0006863592 -0.92024188  1.0081416  1.56234731 -0.9390224
#  [7,] -0.98548216 -0.08107805 -1.60815993 -0.6932373819  0.89797526 -0.8691044  1.24215371  0.8384429
#  [8,]  0.01513086  1.26424109 -2.32237229  0.2608364805 -0.35629514 -0.5151981  1.46129302  0.5291967
#  [9,] -0.25204590 -0.70338819 -1.96721918  0.5066869590  1.03190009 -0.5002165 -0.98583638 -1.0883085
# [10,] -1.46575030 -0.04057817  0.02752681  0.5643018376  0.66430042 -0.2725779  0.92561447 -0.7955874
#              [,9]        [,10]
#  [1,]  0.96832400  1.136878023
#  [2,]  0.18510415  0.004507257
#  [3,] -0.41257000  1.341705472
#  [4,] -0.83292772 -1.365424404
#  [5,]  0.95488318  0.926037646
#  [6,] -2.03609798 -0.497367640
#  [7,]  0.07445361 -0.860184103
#  [8,] -0.91453141 -0.060824754
#  [9,]  0.15602420  1.410276163
# [10,]  0.02934662  0.003944793

apply(x, 2, FUN = function(x) sort(x, decreasing = T)[1:floor(length(x)/2)])
#            [,1]       [,2]        [,3]      [,4]       [,5]       [,6]     [,7]      [,8]       [,9]
# [1,] 1.99469634 1.26424109  0.41719084 0.8869350 1.03190009  1.9882438 1.740170 2.1879180 0.96832400
# [2,] 0.71114251 0.67077922  0.24914817 0.8852306 0.95048417  1.6756248 1.562347 1.2174872 0.95488318
# [3,] 0.18540528 0.49382018  0.02752681 0.5643018 0.89797526  1.0081416 1.461293 1.1339939 0.18510415
# [4,] 0.10877555 0.09147291 -0.32646679 0.5066870 0.66430042  0.9697466 1.306277 0.8384429 0.15602420
# [5,] 0.01513086 0.03960243 -0.34041599 0.4836041 0.06116275 -0.2725779 1.242154 0.7314502 0.07445361
#            [,10]
# [1,] 1.410276163
# [2,] 1.341705472
# [3,] 1.136878023
# [4,] 0.926037646
# [5,] 0.004507257

编辑只返回一半的非 NA 值:

apply(x, 2, FUN = function(x) sort(x, decreasing = T)[1:floor(sum(!is.na(x))/2)])

这将返回一个列表,其中每个项目是每个原始列中非缺失值数量的一半长度(向下舍入)的向量。如果碰巧每一列的长度相同,它将被强制转换为矩阵,除非该长度为 1,在这种情况下它将是一个向量。

【讨论】:

  • 我试图想办法避免 apply 和循环遍历行,但我无法在速度上击败它 - replace(x, TRUE, x[order(col(x), -x)])[1:floor(nrow(x)/2),] 是我能做的最好的。
  • order(col(x), -x) 很聪明!我很惊讶它没有更快。虽然看起来 order 在幕后分享了 applying,所以也许它真的没有那么不同。
  • 由于我的 NA 散布在每列中,因此每列中正值的数量不同。您的建议削减了整个数据的一半,并将 NA 留在阳性数最少的列中。我希望的结果是每列只有一半的正数而没有任何 NA。我认为您的建议是正确的,但仍然适用于每一列,它只适用于整个数据。
  • 我要编辑,但我很想告诉你问一个新问题。此评论包含许多应该包含在您的问题中的信息,并从一开始就在可重复的示例中进行了演示。为每一列返回一个不同长度的向量是完全不同的。而不是返回矩形数据。我强烈建议您阅读making good reproducible examples 并在您提出另一个问题之前重复地共享输入和所需的输出。
猜你喜欢
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
相关资源
最近更新 更多