如何将自定义函数应用于数据框的每一列

时间:2019-05-12 18:35:24

标签: r dplyr

我试图摆脱tidyverse和dplyr方法的束缚,并希望将以下函数应用于数据框/数据表的每一列:

library(multimode)
funx <- function(x) {multimode::modetest(x, method = 'SI') }

,然后尝试使用诸如summary_all之类的内容开始,但是我立即收到错误消息:

  

错误:列mpg的长度必须为1(汇总值),而不是8

library(dplyr)

mtcars %>%
     summarise_all(funx)

我希望最终得到一个新的数据框,该数据框显示在第1列中测试的colname,在第2列中显示modetest的p值

自昨天(23-05-2019)更新软件包以来,我的解决方案无法正常工作,以下代码现在显示为“。”。点而不是列名 向github页面提交了一个帖子,以询问此更改的原因:github

library(multimode)
funx <- function(x) {
    print(substitute(x))
    multires <- multimode::modetest(x, method = 'SI') 
    p <- multires$p.value}

mtcars %>% 
    select(1:2) %>%
    summarise_all(list(~ funx(.)))

更新具有讽刺意味的是,在收到有关github帖子的反馈后,对于新版本,我们现在可以执行以下操作:

   mtcars %>%
      select(1:2) %>%
        summarise_all(funx)

正如您所看到的,这与我在发布此问题时开始提出问题的语法完全相同。因此,我想说dplyr团队所做的出色工作使语法更加“自然”。

1 个答案:

答案 0 :(得分:4)

summarise只能与单个元素一起输出。根据{{​​1}}

  

创建一个或多个标量变量,以汇总现有tbl的变量。具有由group_by()创建的组的Tbl将在每个组的输出中导致一行。没有组的表将排成一行。

因此,如果输出大于长度1,则将其包装在?summariselist

unnest

如果我们要提取单个值,例如library(dplyr) out <- mtcars %>% summarise_all(list(~ list(funx(.)))) ,则无需将其包装在p.value

list

可以使用out1 <- mtcars %>% select(1:2) %>% summarise_all(list(~ funx(.)$p.value)) out1 # mpg cyl #1 0.718 0.244

将其转换为两列数据集
gather

通过检查library(tidyr) gather(out1, colName, pvalue) %>% arrange(pvalue) 在单列上的输出

modetest

它不是单个值输出,而是摘要模型输出。因此,最好将其存储在funx(mtcars[[1]]) # Silverman (1981) critical bandwidth test #data: x #Critical bandwidth = 2.5413, p-value = 0.716 #alternative hypothesis: true number of modes is greater than 1 中,但是,我们可以提取特定的组件(list)并将其输出到p-value