【问题标题】:Naming list elements as they go through a loop在循环中命名列表元素
【发布时间】:2022-01-12 01:44:25
【问题描述】:

正如我在几天前的上一个问题 (Pairwise t test loop through dataframes contained in a list) 中提到的,我有一个大型数据框,可以通过以下方式模仿:

exampledf <- data.frame(Item = c("A", "B", "C", "A", "B", "C", "A", "B", "C"), 
             Value=runif(9), 
             Condition=c("Control","Control","Control", "Test", "Test", "Test",  "Placebo", "Placebo", "Placebo"))

我通过使用 dplyr 过滤项目 A、项目 B、项目 C 等将这个 df 拆分为一个列表

Listdf <- split(exampledf, Item)

我在之前的问题上得到了帮助,通过这些单独的数据帧中的 pairwise.t.test 循环,例如,对项目 A 的不同条件之间的测量值进行成对比较。我使用的代码如下所示:

p <-list() 
for (i in 1:length(Listdf)) {
  p[[i]] <- pairwise.t.test(Listdf[[i]]$Value, Listdf[[i]]$Condition, p.adjust = "none")
}
p

我也得到了代码的建议:

lapply(1:length(Listdf), function(x) {pairwise.t.test(Listdf[[x]]$Value, Listdf[[x]]$Condition, p.adjust = "none")})

我现在的问题是这两个选项都会循环并执行 t.tests,它们会吐出到 p 列表中。但是,在这种情况下,“i”的名称与 p 列表中的哪个 pairwise.t.test 结果有关。

我使用 lapply 尝试了这种方法,并定义了一个保留名称的函数,但它不起作用,只是吐出与以前相同的 p 列表:

lapply_preserve_names <- function(list, fun){
  lapply(seq_along(list), function(i) {
    obj = list[i]
    names(obj) = names(list)[i]
    fun(obj)
  })
}
p_names <- lapply_preserve_names(1:length(Listdf), function(x) {pairwise.t.test(Listdf[[x]]$Value, Listdf[[x]]$Condition, p.adjust = "none")})

我也试过

for (i in 1:length(Listdf)) {
  assign(paste("Pvalue", i, sep = "_"), pairwise.t.test(Listdf[[i]]$Value, Listdf[[i]]$Condition, p.adjust = "none"))
}

for (i in 1:length(Listdf)) {
  p[[i]] <- pairwise.t.test(Listdf[[i]]$Value, Listdf[[i]]$Condition, p.adjust = "none")
  assign(paste("Pvalue", i, sep = "_"), Listdf[[i]]$Item))
}

我认为我的问题的症结在于将 assign 函数与前面描述的循环相结合,从而生成列表 p。有谁知道如何更有效/更正确地做到这一点?

我还想知道是否有一种方法可以将列表中的结果收集成某种图,有点像包装 ggplot 的分面,但表格包含 p 值而不是单个图。

如果您能提供任何建议或提示,我将不胜感激!

【问题讨论】:

    标签: r list loops


    【解决方案1】:

    当执行拆分时,列表中的元素被命名。可以提取该名称列表并将其分配给成对语句的结果。

    names(p) &lt;- names(Listdf) 会为你工作。

    #create sample data
    exampledf <- data.frame(Item = c("A", "B", "C", "A", "B", "C", "A", "B", "C"), 
                            Condition=c("Control","Control","Control", "Test", "Test", "Test",  "Placebo", "Placebo", "Placebo"))
    
    exampledf <- rbind(exampledf, exampledf)
    exampledf$Value=runif(18)
    
    library(broom)
    #split
    Listdf <- split(exampledf, exampledf$Item)
    
    #perform calculation
    p<-lapply(Listdf, function(x) {
       broom::tidy(pairwise.t.test(x$Value, x$Condition, p.adjust = "none"))})
    
    names(p)<-names(Listdf)
    
    #create a trable of pvalues
    #assumes table is in the same order for each list element
    answer<-p[[1]][,1:2]
    for (name in names(p)) {
       answer[[name]]<-p[[name]][,"p.value"]
    }
    answer
    # A tibble: 3 × 5
      group1  group2  A$p.value B$p.value C$p.value
      <chr>   <chr>       <dbl>     <dbl>     <dbl>
    1 Placebo Control    0.168      0.666     0.883
    2 Test    Control    0.0772     0.434     0.439
    3 Test    Placebo    0.0210     0.701     0.519
    

    【讨论】:

    • names(p) &lt;- names(Listdf) 确实为我工作!非常感谢你。但是,我仍在努力在某种图中收集所有列表元素,该图中显示了每个项目的成对 t.test 结果。
    • 对不起,我是简短的 OOTO,是的,这很有帮助!非常感谢您的建议!
    猜你喜欢
    • 1970-01-01
    • 2016-03-03
    • 2020-04-23
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 2017-10-28
    • 2021-10-16
    相关资源
    最近更新 更多