如何将 lapply() 与 aov() 一起使用,因为结果 returns 没有 p 值和 f 值,而只是 "Class" 和模式的列表”?

How to use lapply() with aov() because results returns no p-value and f-value but just a list of "Class" and Mode"?

我有这个示例数据。我想要做的是获取 p 值并比较每个数据框中的每个人。我尝试在 kruskal.test() 中通过管道传输数据框列表并且它有效但是当在 aov() 中使用 lapply() 传递相同的数据框时,我没有得到结果。抱歉,我是 R 的新手。我只是想学习如何在数据框列表中应用 lapply() 函数。另一个有用的信息可能是身高和体重列中的所有值都是根据先前较大的数据帧计算得出的平均值。

df_list <- list(
  `1.3.A` = 
    tibble::tribble(
      ~Person, ~Height, ~Weight,
      "Alex",    175L,     75L,
      "Gerard",    180L,     85L,
      "Clyde",    179L,     79L,
      "Alex",    175L,     75L,
      "Gerard",    180L,     85L,
      "Clyde",    179L,     79L

    ),
  `2.2.A` = 
    tibble::tribble(
      ~Person, ~Height, ~Weight,
      "Alex",    175L,     75L,
      "Gerard",    180L,     85L,
      "Clyde",    179L,     79L,
       "Alex",    175L,     75L,
      "Gerard",    180L,     85L,
      "Clyde",    179L,     79L
    ), 
  `1.1.B` = 
    tibble::tribble(
      ~Person, ~Height, ~Weight,
      "Alex",    175L,     75L,
      "Gerard",    180L,     85L,
      "Clyde",    179L,     79L,
      "Alex",    175L,     75L,
      "Gerard",    180L,     85L,
      "Clyde",    179L,     79L
    )
)

我希望有人能让我明白,当我将 lapply()kruskal.test() 一起使用时,我能够获得 p 值,但是当我 运行 aov() 并执行 summary(),我得到一个没有 p 值的列表。

这是输出:

  Length Class Mode
1.3.A 6     aov   list
2.2.A 6     aov   list
1.1.B 6     aov   list

当 运行 宁和访问列表中的特定数据帧时,我得到一个 p 值和 f 值。此代码为我提供了特定数据帧的正确输出? 这是我使用的代码:

cary <- aov(df_list[["1.3.A"]]$Height ~ df_list[["1.3.A"]]$Person)
summary(cary)

我不明白的是,为什么 lapply() 在这两个不同的测试中表现不同?为什么当我在 aov() 中使用 lapply() 时它不起作用,但是当我单独使用 aov() 访问单个数据帧时,它给出了预期的结果?

失败的尝试:

mut <- lapply(df_list, function(x) with(x, aov(Height ~ Person, data = x)))
mud <- summary(mut)
mud
cow <- purrr::map(df_list, ~ aov(Height ~ Person, data = .x))
cow
summary(cow)
tree <- function(df) {
  aov(Height ~ Person)
}
shrub <- lapply(df_list, tree)
summary(shrub)

我不确定您应用这些测试的目的。 如果下面的代码是您的目的,

    cary <- aov(df_list[["1.3.A"]]$Height ~ df_list[["1.3.A"]]$Person)
    summary(cary)

kruskal wallis 检验给出的 p 值是

    lapply(df_list, kruskal.test)

那么我不确定上面代码的 p 值是否正确。 该代码将打印警告消息 在 kruskal.test.default(X[[i]], ...) 中: 'x' 的某些元素不是数字,将被强制转换为数字

这个被胁迫的人的名字是数字。 它很乱,但下面的代码可能很乱,但提供了更好的 p 值

    lapply(df_list, function(x) (kruskal.test(x$Height ~ x$Person)))
    lapply(df_list, function(x) summary(aov(x$Height ~ x$Person)))

编辑: 如果您只想获得 p 值,

    lapply(df_list, function(x) (kruskal.test(x$Height ~ x$Person)$p.value))
    lapply(df_list, function(x) summary(aov(x$Height ~ x$Person))[[1]]$`Pr(>F)`[1])

会做。

编辑 2(回复评论)

  1. 如果你想让你的树函数在不使用 $ 的情况下工作,那么你应该将代码更改为

    tree <- function(df) {   aov(Height ~ Person, data = df) } 
    

    tree <- function(df) {   aov(df$Height ~ df$Person) } 

然后,打印 p 值,而不是使用

    summary(shrub)

使用

    lapply(shrub,summary)
  1. 因为我使用lapply,所以它适合列表的每个数据框的方差分析。 要从汇总结果中调用 p 值,请尝试下面的拟合代码

     x<-summary(aov(Height~Person, df_list[[1]]))
    

然后你会看到 x 是 1 的列表并调用 x 的组件,因为 x 中只有一个元素,所以我调用 [[1]]

然后,x 具有矩阵形式

    x[[1]]$`Pr(>F)`

它将打印

    [1] 1.433592e-42           NA

我想删除 NA 所以我将 [1] 添加到末尾

    x[[1]]$`Pr(>F)`[1]

你做错了。

summary 是智能的,它会根据其输入调整显示哪种摘要。如果输入是 aov 的结果,您将获得 p 值等。但如果输入的是 aov 结果列表,那么你将一无所获。

a <- lapply(list(iris1 = iris, iris2 = iris),
            function(df) aov(Sepal.Length ~ Species, data = df))
 
summary(a)

# Length Class Mode
# iris1 13     aov   list
# iris2 13     aov   list
# 

lapply(a, summary)

# $iris1
#              Df Sum Sq Mean Sq F value Pr(>F)    
# Species       2  63.21  31.606   119.3 <2e-16 ***
# Residuals   147  38.96   0.265                   
# ---
# Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# 
# $iris2
#              Df Sum Sq Mean Sq F value Pr(>F)    
# Species       2  63.21  31.606   119.3 <2e-16 ***
# Residuals   147  38.96   0.265                   
# ---
# Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

但是,如果目标是提取 p 值以便在其他计算中使用它(也就是说,不仅仅是在屏幕上显示 p 值),那么事情会变得有点复杂:

str(summary(a[[1]]))

#List of 1
#  $ :Classes ‘anova’ and 'data.frame': 2 obs. of  5 variables:
#   ..$ Df     : num [1:2] 2 147
#   ..$ Sum Sq : num [1:2] 63.2 39
#   ..$ Mean Sq: num [1:2] 31.606 0.265
#   ..$ F value: num [1:2] 119 NA
#   ..$ Pr(>F) : num [1:2] 1.67e-31 NA
#  - attr(*, "class")= chr [1:2] "summary.aov" "listof"

也就是说,它是一个包含 1 个元素的列表,所以我们首先要用 [[1]] 获取这个元素,然后你必须获取名为 Pr(>F) 的第 5 个元素,然后它是结果向量的第一个元素。因此:

summary(a[[1]])[[1]]$`Pr(>F)`[[1]]
# 1.669669e-31

那你可以做

sapply(a, function(aov.result) summary(aov.result)[[1]]$`Pr(>F)`[[1]])
#        iris1        iris2 
# 1.669669e-31 1.669669e-31 

并获得 F 值:

t(sapply(a, function(aov.result) {
  summ <- summary(aov.result)
  c(F = summ[[1]]$`F value`[[1]],
    p = summ[[1]]$`Pr(>F)`[[1]])
}))

#              F            p
# iris1 119.2645 1.669669e-31
# iris2 119.2645 1.669669e-31