当列表名称匹配时,指定数据框中的值

Specify value from data frame when list name matches

提问人:heikeehee 提问时间:9/22/2023 最后编辑:Markheikeehee 更新时间:9/22/2023 访问量:36

问:

我有一个非常大的嵌套列表,我想从每个嵌套列表中随机抽取一个样本,但每个列表的样本大小不同。样本数量在数据框中定义。我想编写一个函数,将第一级列表的名称与数据框中的相应条目相匹配,然后定义所需的样本量。

这是我嵌套列表的更简单版本。

mydf <- data.frame(
  name = c("A", "B", "C", "D"),
  n = c(5, 18, 25, 7))

df1 <- data.frame(matrix(1:10, nrow = 5, ncol=3))
df2 <- data.frame(matrix(1:10, nrow = 15, ncol=3))
df3 <- data.frame(matrix(1:10, nrow = 20, ncol=3))
df4 <- data.frame(matrix(1:10, nrow = 40, ncol=3))
df5 <- data.frame(matrix(1:10, nrow = 27, ncol=3))
df6 <- data.frame(matrix(1:10, nrow = 78, ncol=3))

list1 <- list(df1 = df1, df2 = df2, df3 = df3)
list2 <- list(df1 = df4, df2 = df5, df3 = df6)
list3 <- list(df1 = df2, df2 = df5, df3 = df4)
list4 <- list(df1 = df6, df2 = df3, df3 = df1)

mylist <- list("A" = list1, 
               "B" = list2,
               "C" = list3,
               "D" = list4)


mylist

我编写了一个解决方法,其中我逐个提取第一个级别列表并指定要匹配的名称,但这需要我多次复制代码。理想情况下,我想自动执行此步骤。

最终,我需要运行此步骤数千次,因此它需要高效。

library(purrr)
set.seed(0)

A <- mylist$A
A2 <- lapply(A, function(df){
  N <- pluck( n, 'n', which(mydf$name == 'A')) 
  rd <- function(x) sample(x, size = N, replace =TRUE)
  df <- apply(df, 2, rd)
  })

A2
r lapply purrr 嵌套列表

评论

0赞 Mark 9/22/2023
Error in FUN(X[[i]], ...) : object 'n' not found.我无法让你的代码运行,所以我将不得不投票关闭 rn

答:

1赞 Nir Graham 9/22/2023 #1

我认为任务更容易,列表操作更少,表更多。 但我承认,由于要采样的各种帧之间的列一致性,我可能对此有偏见。尽管如果它们的大小不同,则带有嵌套的版本可能会起作用。


library(tidyverse)

(mylongdata <- bind_rows(
  map(mylist, \(x){
    bind_rows(x, .id = "inner_id")
  }), .id = "outer_id"
))

inner_func <- function(name, n) {
  filter(
    mylongdata,
    outer_id == name
  ) |>
    group_by(inner_id) |>
    dplyr::slice_sample(
      n = n,
      replace = TRUE
    )
}

sample_results <- map2(
  mydf$name,
  mydf$n, inner_func
)

评论

0赞 heikeehee 9/23/2023
了不起!效果很好,非常感谢。这些列在我的数据中是一致的。