【问题标题】:Randomly extract elements in a list which belongs to a list and know the postition随机提取列表中属于列表并知道位置的元素
【发布时间】:2021-10-23 18:36:56
【问题描述】:

我有一个包含几个这样的列表的列表:

example_list <- list(c(1,2,3,4),c(1,0,0,0,1),matrix(1:12,3,4),matrix(1:12,4,3))

如何从 example_list 中随机抽取一个元素,并准确知道该元素的位置?例如,如果我选择了 1,我怎么知道这个 1 是第二个列表的第一个元素而不是其他任何元素?返回的应该是子列表的顺序,也是子列表中元素的顺序。

请注意,所有子列表均由数字组成,而不是字符串或字符。

我已经搜索过,但仍然没有找到合适的解决方案,有人可以帮助我吗?真的很感激!

【问题讨论】:

    标签: r


    【解决方案1】:

    我想这就是你想要的:

    set.seed(99)
    sample_list <- function(x) {
      i <- sample(length(x), 1)
      list(i, x[[i]])
    }
    
    sample_list(example_list)
    

    给予:

    [[1]]
    [1] 4
    
    [[2]]
         [,1] [,2] [,3]
    [1,]    1    5    9
    [2,]    2    6   10
    [3,]    3    7   11
    [4,]    4    8   12
    

    【讨论】:

    • 谢谢!很抱歉我可能没有清楚地提出我的问题。我只能选择一个元素,或者我应该在列表中说出值。在我的示例中,这应该只是一个数字(1 或 2 或 3 等)。您的答案只是将订单和该订单的内容联系在一起。例如,如果系统随机选择了 1,我得到的返回信息是这样的:2, 5,那么我知道这个 1 只是来自整个列表的第二个元素,它是它的小列表的第五个值.
    【解决方案2】:

    我们可以用list的序列命名list,并在melted数据上使用sample

    library(reshape2)
    d1 <- melt(setNames(example_list, seq_along(example_list)))
    

    现在执行sample 并获取相应的list 索引以及行/列索引

    > d1[d1$value == sample(d1$value, 1),]
       value Var1 Var2 L1
    19    10    1    4  3
    31    10    2    3  4
    

    【讨论】:

    • 谢谢!但是,我认为这是如何提取列表列表的解决方案。从输出中,我只能知道随机选择的整个列表中值的顺序。例如,您向我展示了您随机选择了列表的第四个元素,这不是我想要的。我只能选择一个值,例如值5,返回会告诉我,这是来自大整列表的第四个列表,在第一行第二列。结果应该给我这样的信息:4,[1,2]。
    • @MD_Yang 也许更新有帮助
    【解决方案3】:

    this 问题的答案可能适用于您的示例:

    library(data.table)
    
    f <- list(c(1,2,3,4),c(1,0,0,0,1),matrix(1:12,3,4),matrix(1:12,4,3))
    dt <- data.table::melt(f)
    setcolorder(setcolorder(dt, sort(colnames(dt))), "value")
    

    f 采样值与采样dt$value 相同。如果对行i进行采样,则可以从f中检索到相应的值:

    i <- sample(nrow(dt), 1)
    ifelse(is.na(dt$Var1[i]), f[[dt$L1[i]]], f[[dt$L1[i]]][dt$Var1[i], dt$Var2[i]])
    

    但是,列表结构可能会变得非常复杂。上述解决方案不适用于以下对象,该对象包含嵌套在嵌套列表中的矩阵的 3 维列表数组:

    set.seed(94)
    f <- list(c(1:4), c(1, 0, 0, 0, 1), matrix(1:12, 3, 4), list(matrix(1:12, 4, 3), `dim<-`(lapply(1:18, function(i) matrix(sample(1:10, 4), nrow = 2)), c(3,3,2))))
    

    这是一个递归函数,它将返回一个data.table,其中包含对象中每个值的地址。 i 列中的正值表示列表索引(使用双括号访问),负值表示向量/矩阵/数组索引(使用单括号访问)。请注意,它对矩阵和数组使用一维索引。

    library(data.table)
    
    faddress <- function(obj) {
      if (is.atomic(obj)) {
        return(data.table(i = -seq_along(obj)))
      } else {
        return(rbindlist(lapply(seq_along(obj), function(i) cbind(i, faddress(obj[[i]]))), fill = TRUE))
      }
    }
    

    使用cbind 将值附加到生成的data.table

    dt <- cbind(unlist(f), faddress(f))
    

    例如dt的第94行是:

    > dt[94]
       V1 i1 i2 i3 i4
    1:  1  4  2 16 -1
    

    1 的值通过以下方式检索:

    > f[[4]][[2]][[16]][1]
    [1] 1
    

    【讨论】:

      【解决方案4】:

      感谢@akrun 提醒我melt() 函数。这是我的问题的解决方案:

      example_list <- list(matrix(c(1,2,3,4)),matrix(c(1,0,0,0,1)),matrix(1:12,3,4),matrix(1:12,4,3))
      # To avoid getting NA, I transform arrays in list to matrix, so that I can get the index of rows and columns.
      get_res <- function(example_list){
      output <- melt(setNames(example_list,seq_along(rates)))
      res <- output[sample(dim(output)[1], 1),] # sample(dim(output)[1], 1) This confirms I get only one number
      if (as.integer(res$L1) <= 2){
      ind1 = res$L1
      ind2 = res$Var1}
      else{ind1 = res$L1
      ind2 = c(res$Var1,res$Var2)}
      result <- list(ind1 = ind1, ind2 = ind2)
      return(result)}
      get_res(example_list)
      

      in1 告诉随机数所属的子列表,ind2 告诉随机数在这个子列表中的顺序。

      【讨论】:

        猜你喜欢
        • 2011-04-26
        • 2012-09-08
        • 2017-11-10
        • 2015-09-22
        • 2013-12-17
        • 1970-01-01
        • 1970-01-01
        • 2012-02-07
        • 1970-01-01
        相关资源
        最近更新 更多