【问题标题】:Alternative to case_when() for assigning a function to a variable in R替代 case_when() 将函数分配给 R 中的变量
【发布时间】:2018-12-31 14:08:51
【问题描述】:

一个(我希望)非常简单的问题。我想使用 case_when() 或与之等效的东西作为一个干净的解决方案,根据变量的值分配要使用的函数。所以,我想做这样的事情:

library(tidyverse)
library(lubridate)
library(nycflights13)
#small data frame of new years day flights from JFK
df1<-flights %>% filter(year==2013,month==1,day==1,origin=="JFK")  

#use min_ind as an indicator (in practice this would be a variable from my dataset
min_ind<-1

现在,我想要一种简单的方法来根据 min_ind 的值将函数分配给 func_test。我可以这样做:

  if(min_ind==1)
    func_test<-min
  if(min_ind!=1)
    func_test<-max
#test it
func_test(df1$distance)
#reverse
min_ind<-0
  if(min_ind==1)
     func_test<-min
  if(min_ind!=1)
     func_test<-max
func_test(df1$distance)

这很好用。当 min_ind 为 1 时,我得到最小值,当它不是 1 时,我得到最大值。我想做的是通过 case_when() 来完成这项任务,因为我有一组 4 或 5 个函数,我可能想对数据中的值使用条件。这样的事情可能吗?

func_test<-case_when(
  min_ind==1 ~ min,
  min_ind!=1 ~ max
)

我收到错误代码 Error in value[[1]][rep(NA_integer_, m)] : 'builtin' 类型的对象不是子集

感谢您的任何建议。

【问题讨论】:

  • 听起来你可能正在寻找base::switch()

标签: r case-when


【解决方案1】:

case_when 确实被设计为矢量化函数。所以公式的两边都应该是类似向量的、长度相同或可回收的东西。函数的行为不像集合。问题是如果min_ind 不是长度为 1 的向量,事情就会变得一团糟。基本上它试图检查长度是否兼容。在此处查看您收到的错误消息

min_ind <- 1
func_test<-case_when(
  min_ind==1 ~ 1:3,
  min_ind!=1 ~ 4:6
)
# Error: RHS of case 1 (1:3) must be length 1 (the first output), not 3

所以你最初得到的错误消息基本上是因为它试图将你的函数的长度扩展到与输入相同的长度,这对于函数来说又没有意义。如果您确定length(min_ind==1)

,您可以将函数填充到列表中,然后提取第一个元素
min_ind <- 1
func_test<-case_when(
  min_ind==1 ~ list(min),
  min_ind!=1 ~ list(max)
)[[1]]

【讨论】:

  • 不错!在您发布您的解决方案的同时,我得到了完全相同的解决方案。 :)
  • 谢谢,非常感谢!
【解决方案2】:

如果您查看case_when 内部,您会发现它试图将 RHS 值视为一个列表,当您使用基本函数时,R 不喜欢这样。以下是一种解决方法:

func_test<-case_when(
     min_ind==1 ~ list(min),
     min_ind!=1 ~ list(max)
 )[[1]]

此解决方案将函数放入它们自己的列表中,然后在将它们分配给 func_test 之前将其提取出来。

【讨论】:

  • 谢谢!非常感谢。
【解决方案3】:

好吧,您的错误是min 没有引用上述代码中的任何内容。 应该是:

func_test<-case_when(
   min_ind==1 ~ min(df1$distance),
   TRUE ~ max(df1$distance)
)

TRUE 在只有一个其他选项时使用:索引可以是 1,也可以不是 1。

这行得通;)

【讨论】:

  • 谢谢。这将适用于值,但我想要的是附加到变量的函数,因此我可以稍后使用 func_test 调用该函数。
猜你喜欢
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 2018-12-26
  • 1970-01-01
相关资源
最近更新 更多