【问题标题】:Using the function with multiple outputs (non-summary fxn?) with summarize使用带有多个输出(非汇总 fxn?)的函数和汇总
【发布时间】:2016-05-26 17:37:19
【问题描述】:
library(OptimalCutpoints)

library(dplyr)

这是一个测试数据:

set.seed(123)

df<-data.frame(label=rbinom(1000,size=1,prob=0.5),score=rnorm(1000),type=sample(c("A","B","C","D"),1000,replace=TRUE))

使用 group_by 对“类型”进行分组,并希望使用 library(OptimalCutpoints) 中的 optimization.cutpoints 函数进行总结

df%>%group_by(type)%>%summarize(Opt_cut=optimal.cutpoints(X = "score", status = "label", tag.healthy = 0, methods = "MaxSpSe",data=df[,1:2]))

我得到了这个: Error: expecting a single value

我可以得到这样的解决方法,提取每个“类型”并分别运行 optimize.cutpoints:

df_A<-df%>%filter(grepl("A",type))
opt.cut.df.A <- optimal.cutpoints(X = "score", status = "label", tag.healthy = 0, methods = "MaxSpSe", data = df_A)

从 opt.cut.df.A 我可以像这样提取最佳截止:

opt.cut.df.A[1]$MaxSpSe$Global$optimal.cutoff$cutoff

但这绝对不是最好的方式,尤其是。有大量的“类型” 除非我遗漏了什么,否则 summarise 似乎只适用于单个输出函数。

问题:如何在summary中使用optimal.cutpoints或类似函数?

【问题讨论】:

  • 该函数输出一个嵌套列表,而 summarize 并不期望这样。你只想要一个切割点吗?
  • 嗨皮埃尔,在这种情况下是的......但我的一般问题是如何总结具有在 dplyr 中输出 >1 值的函数的组。我认为下面 Psidom 的应用拆分解决方案效果很好!在这种情况下,也许 dplyr 不是最好的方法。
  • 我使用了data.table,速度非常快。我试过dplyr,但找不到方法
  • summarize 可以输出列表列,可以通过 tidyr unnest 取消嵌套。有关summarize 和列表列的示例,请参阅here。但是,您的特定案例/功能似乎无法正常工作 - 我收到关于 dimnames 长度不等于数组范围的错误...
  • @StevenBeaupré 啊是的......这里是新手......不知道那个选项。谢谢。我发现 data.table 解决方案最简单......主要是因为我对 purr 不太熟悉。

标签: r function dplyr


【解决方案1】:

使用purrr的另一种选择:

library(purrr)

df %>%
  split(.$type) %>%
  map(~ optimal.cutpoints(X = "score", status = "label", 
                          tag.healthy = 0, methods = "MaxSpSe", data = .)) %>%
  map(c("MaxSpSe", "Global", "optimal.cutoff", "cutoff"))

这给出了:

#$A
#[1] -0.0768659
#
#$B
#[1] 0.1612264 0.1830480
#
#$C
#[1] -0.08671413
#
#$D
#[1] 0.1071904 0.1155321 0.1390979

如果你想在 data.frame 中得到结果,你可以在链中添加map_df

df %>%
    split(.$type) %>%
    map(~optimal.cutpoints(X = "score", status = "label", 
                           tag.healthy = 0, methods = "MaxSpSe", data = .)) %>% 
    map(c("MaxSpSe", "Global", "optimal.cutoff", "cutoff")) %>% 
    map_df(~data.frame(cutoff = .), .id = "type")

这给出了:

#  type      cutoff
#1    A -0.07686590
#2    B  0.16122635
#3    B  0.18304797
#4    C -0.08671413
#5    D  0.10719041
#6    D  0.11553210
#7    D  0.13909786

【讨论】:

  • 我也在想 purrr 可能也适用于此。通过添加map_df(as.data.frame, .id = "type"),您可以强制转换为data.frame,但我还没有弄清楚如何命名截止值列。
  • @aosmith 我试图找出相同的结果并最终放弃;P 如果您碰巧找到它,请随时更新我的​​帖子。在某些时候,我使用data.table::melt() 并设法拥有valueL1
【解决方案2】:
library(data.table)
setDT(df)[,opt(.SD), by=type]
   type          V1
1:    A -0.07686590
2:    D  0.10719041
3:    D  0.11553210
4:    D  0.13909786
5:    B  0.16122635
6:    B  0.18304797
7:    C -0.08671413

opt 是剪切函数:

opt <- function(df) optimal.cutpoints(X = "score", status = "label", tag.healthy = 0, methods = "MaxSpSe", data=df)[1]$MaxSpSe$Global$optimal.cutoff$cutoff

dplyr 不起作用的原因是因为有时一个组有一个分界点,有时它有多个分界点。 summarise 只等待一个值,混合长度向量会产生问题。

【讨论】:

  • 谢谢!..是的,我认为截止值可能有>1个值不在我的脑海中。
【解决方案3】:

您也可以使用splitapply 方法,生成模型列表,然后从列表中提取值。

listOfModels <- lapply(split(df, df$type), function(subDf) 
                       optimal.cutpoints(X = "score", status = "label", 
                                         tag.healthy = 0, methods = "MaxSpSe",data=subDf))

lapply(listOfModels, function(model) model[1]$MaxSpSe$Global$optimal.cutoff$cutoff)

$A
[1] -0.0768659

$B
[1] 0.1612264 0.1830480

$C
[1] -0.08671413

$D
[1] 0.1071904 0.1155321 0.1390979

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    相关资源
    最近更新 更多