【问题标题】:How to select randomly rows and columns in each row in a list如何在列表的每一行中随机选择行和列
【发布时间】:2019-11-14 20:25:18
【问题描述】:

我有一个列表,其中有一个 5x5 矩阵数据集。我想随机选择 2 行,并且在每一行中我想选择 3 个元素,不一定来自相同的列。

所以,我生成了三个数据集并列了一个列表。我能够随机选择 2 行,但很难随机选择 3 个元素而不是选择列。

这是我的代码。

    ### Generate three data sets
    dat1 <- (matrix(rnorm(25), ncol=5))
    dat2 <- (matrix(rnorm(25), ncol=5))
    dat3 <- (matrix(rnorm(25), ncol=5))

    all.dat <- list(dat1=dat1, dat2=dat2, dat3=dat3)
    all.dat

    #$`dat1`
    #           [,1]      [,2]       [,3]        [,4]       [,5]
    #[1,]  1.4394742 0.7064418 -1.3472468  0.52847179 -0.7642337
    #[2,]  0.2490570 0.7510308 -0.7028238 -0.09730666 -0.6340773
    #[3,]  0.8981850 0.7592610  0.9139721 -0.45700647 -0.2727481
    #[4,] -1.0467119 0.2147032 -3.2104254 -0.17797056  0.8897180
    #[5,] -0.5437118 0.5803862 -0.1814992  1.93316139 -1.3708932

    #$dat2
    #          [,1]       [,2]          [,3]         [,4]       [,5]
    #[1,] 1.0442187 -1.4156893  0.5606035101 -1.350030718  0.1538721
    #[2,] 0.2080905 -1.7748005  0.8620324724 -0.169071336 -1.7537700
    #[3,] 0.9153835 -0.9884572 -1.7279901136 -1.334516414  0.5773021
    #[4,] 0.1359423 -1.5107088 -1.4289650078 -0.002001498 -0.4712699
    #[5,] 0.1695023 -0.7315209 -0.0003996577 -1.043326258  1.2939485

    #$dat3
    #           [,1]        [,2]         [,3]       [,4]       [,5]
    #[1,] -1.4994878 -0.59179084  0.998017255  1.4021344  0.5929842
    #[2,]  0.3424003  1.33568858  2.214968765 -0.2434351  1.3588000
    #[3,] -1.0117892  0.91065720 -0.761932994 -0.8117838 -0.4094731
    #[4,] -0.1694781 -0.02937177 -0.826337270  0.2178774 -0.6427046
    #[5,]  0.3413101 -0.56911900  0.001363063  0.5579126 -0.9373204

    ### Select rows and columns.
    all.dat.sel.1 <- 
    lapply(all.dat, function(x) {
    x[sample(nrow(x), size = 2), sample(ncol(x), size = 3)]
    })

    all.dat.sel.1

    #$`dat1`
    #           [,1]       [,2]       [,3]
    #[1,] -0.4570065  0.8981850 -0.2727481
    #[2,]  1.9331614 -0.5437118 -1.3708932

    #$dat2
    #              [,1]         [,2]       [,3]
    #[1,] -0.0003996577 -1.043326258  1.2939485
    #[2,] -1.4289650078 -0.002001498 -0.4712699

    #$dat3
    #           [,1]      [,2]       [,3]
    #[1,] -1.4994878 1.4021344  0.9980173
    #[2,] -0.1694781 0.2178774 -0.8263373

然后,我能够随机选择行,但每行中的元素来自相同的列。例如,第 1 行中的值 -1.4994878 和第 2 行中的 -0.1694781 来自 dat3 中的第 1 列。

我想要的是这样的:

    #$dat3
    #           [,1]        [,2]         [,3]
    #[1,] -1.4994878 0.998017255    0.5929842
    #[4,]  0.2178774 -0.02937177 -0.826337270

有一个例子(https://stackoverflow.com/questions/53095050/sample-random-column-for-each-row-in-data-frame)。但是,它适用于数据框而不是列表数据。

【问题讨论】:

  • 您想从每个矩阵中抽取 any 2*3 个元素吗?或者结果行元素是否需要来自相同的原始矩阵行?

标签: r list random lapply sample


【解决方案1】:

利用矩阵是折叠向量这一事实,即具有dim 属性的向量并直接采样 2*3 向量元素。

lapply(all.dat, function(x){
    matrix(sample(x, 2*3), nrow = 2)
})

#$dat1
#           [,1]       [,2]        [,3]
#[1,]  0.5060559 -0.5644520 -0.83717168
#[2,] -0.6937202 -0.4771927  0.06445882
#
#$dat2
#          [,1]      [,2]      [,3]
#[1,] -0.709440 -1.340993 0.5747557
#[2,] -1.068643  1.449496 1.1022975
#
#$dat3
#          [,1]      [,2]         [,3]
#[1,] 0.6482866 0.5630558 -0.007604756
#[2,] 0.6565885 1.3295648 -0.669633580

注意:我已通过调用 set.seed(1234) 启动脚本。

编辑。

在阅读comment by user @Ronak Shah 并再次提出问题后,下面的代码可能是 OP 正在寻找的内容。它与 Ronak 的解决方案相似但不同。在数据创建代码之前,RNG 种子再次设置为1234

lapply(all.dat, function(x){
    t(apply(x[sample(nrow(x), 2), ], 1, sample, size = 3))
})
#$dat1
#           [,1]      [,2]       [,3]
#[1,] -0.4771927 -1.207066  0.5060559
#[2,] -0.4405479  1.084441 -0.9111954
#
#$dat2
#           [,1]       [,2]      [,3]
#[1,]  1.1022975 -0.9685143  1.449496
#[2,] -0.2942939 -0.5012581 -0.280623
#
#$dat3
#           [,1]         [,2]     [,3]
#[1,] -0.3665239 -0.773353424 1.367827
#[2,]  0.3364728 -0.007604756 2.070271

【讨论】:

  • 但这不会从相同的 2 个随机行中获取数据。它从完整的矩阵中获取数据,但我不确定这是否是 OP 的要求。
  • @RonakShah 我真的不知道,会问 OP。
  • 我想我之前弄错了。 OP提到I want to randomly select 2 rows and within each row I want to select 3 elements not necessarily from same columns.
  • 这正是我想要的!我确实想在不替换的情况下获取它们(行或列)(替换 = F)。原始数据在一个列表中有 1000 个数据集,每个数据集中有 20 x 1000 矩阵。感谢大家的帮助!
【解决方案2】:

我认为你想要做的是

row_const <- 2
col_const <- 3

lapply(all.dat, function(x) {
    rand_rows <- sample(nrow(x), size = row_const)
    t(sapply(rand_rows, function(y) sample(x[y, ], col_const)))
})

#$dat1
#           [,1]       [,2]       [,3]
#[1,] 0.07050839 -0.6868529  0.7013559
#[2,] 0.40077145 -1.0260044 -1.9666172

#$dat2
#           [,1]      [,2]      [,3]
#[1,] -0.3059627 -1.138137 2.1689560
#[2,] -0.2950715  0.837787 0.5539177

#$dat3
#          [,1]       [,2]       [,3]
#[1,] 0.3796395 -0.4910312  0.2533185
#[2,] 0.9222675  0.1238542 -1.0185754

它首先从每个矩阵中选择两个随机行,然后从每行中选择 3 个随机元素。

数据

set.seed(123)
dat1 <- (matrix(rnorm(25), ncol=5))
dat2 <- (matrix(rnorm(25), ncol=5))
dat3 <- (matrix(rnorm(25), ncol=5))
all.dat <- list(dat1=dat1, dat2=dat2, dat3=dat3)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    相关资源
    最近更新 更多