【问题标题】:R supplying arguments while using case_when (R vectorization)R 在使用 case_when 时提供参数(R 向量化)
【发布时间】:2020-10-07 15:36:18
【问题描述】:

这是我之前提出的问题 (R apply multiple functions when large number of categories/types are present using case_when (R vectorization)) 的后续问题。不幸的是,我无法找出问题所在。我想我可能已经缩小了问题的根源,并想检查是否有比我更了解的人可以帮助我找出解决方案。

假设我有以下数据集:

set.seed(100)
City=c("City1","City2","City2","City1")
Business=c("B","A","A","B")
ExpectedRevenue=c(35,20,15,19)
zz=data.frame(City,Business,ExpectedRevenue)

这里假设存在 2 个不同的业务,分别名为“A”和“B”。进一步假设存在两个不同的城市City1和City2。我的原始数据集包含约 200K 对多个企业和约 100 个城市的观察。对于每个城市,我都有一个独特的预先编写的函数来计算调整后的收入。我不想通过每个观察/行运行它们,而是使用 case_when 为相关城市运行函数(例如,对城市 1 进行观察,如果可能的话为城市 1 运行矢量化函数,然后移动到城市 2 等等)。

为了便于说明,假设我对这两个城市有以下高度简化的函数。

#Writing the custom functions for the categories here
City1=function(full_data,observation){
  NewSet=full_data[which(full_data$City==observation$City),]
  BusinessMax = max(NewSet$ExpectedRevenue)+10*rnorm(1)
  return(BusinessMax)
}

City2=function(full_data,observation){
  NewSet=full_data[which(full_data$City==observation$City),]
  BusinessMax = max(NewSet$ExpectedRevenue)-1000*rnorm(1)
  return(BusinessMax)
}

这里的这些简单函数实质上是对城市数据进行子集化,并从预期收入中添加 (City1) 或减去 (City2) 一些随机数再一次,这些简单的功能只是为了说明,并不反映实际的功能。我也手动检查功能是否工作,输入:

City1(full_data = zz,observation = zz[1,])
City1(full_data = zz,observation = zz[4,]) 

并得到“29.97808”和“36.31531”。请注意,在上述函数中,由于我添加或减去了一个随机数,因此我希望在同一个城市中获得不同的值,就像我在这里获得的那样。

最后,我尝试使用 case_when 来运行代码如下:

library(dplyr) #I use dplyr here
zz[,"AdjustedRevenue"] = case_when(
  zz[["City"]]=="City1"~City1(full_data=zz,observation=zz[,]),
  zz[["City"]]=="City2"~City2(full_data=zz,observation=zz[,])
)

我收到的输出如下:

   City Business ExpectedRevenue AdjustedRevenue
1 City1        B              35        43.86785
2 City2        A              20       -81.97127
3 City2        A              15       -81.97127
4 City1        B              19        43.86785

这里,对于观察 1 和 4 以及 2 和 3,调整后的值是相同的。相反,我期望的是为每个观察获得不同的值(因为我为每个观察添加或删除了一些随机数;或者至少打算这样做)。在 Martin Gal 对我之前的问题 (https://stackoverflow.com/a/62378991/3988575) 的回答之后,我怀疑这是由于在最后一步中没有正确调用我的 City1 和 City2 函数的第二个参数。但是,我在试图弄清楚为什么以及要做什么来解决它时有点迷失了。

如果有人能指出为什么会发生这种情况以及如何解决此错误,那将非常有帮助。提前致谢!

附: 我也对其他矢量化解决方案持开放态度。我对矢量化比较陌生,没有太多经验,如果有任何建议,我将不胜感激。

【问题讨论】:

  • 您的意思是%in% 还是==。是否应该引用Business=c(B,A,A,B)
  • @akrun 应该引用业务变量。我已经做出改变了。不幸的是,我不知道最后一步中 == to %in% 的作用。我尝试运行它(使用 %in% 而不是 ==)但得到的结果与以前相同。

标签: r vectorization case-when


【解决方案1】:

City 函数转换为dplyr。如果CityMaster 对于最终函数而言过于简化,则可以将mer 移动到case_when 中(如果适用)。如果一个新城市被添加到数据中,那么它将返回NA,直到定义一个案例。

library(dplyr)
CityMaster <- function(data, city) {
  mer <- data %>%
    filter(City == city) %>%
    pull(ExpectedRevenue) %>%
    max()
  case_when(city == 'City1' ~ mer + 10 * rnorm(1),
            city == 'City2' ~ mer - 1000 * rnorm(1),
            TRUE ~ NA_real_)
}

set.seed(100)
zz %>%
  rowwise() %>%
  mutate(AdjustedRevenue = CityMaster(., City))

# A tibble: 4 x 4
# Rowwise: 
  City  Business ExpectedRevenue AdjustedRevenue
  <chr> <chr>              <dbl>           <dbl>
1 City1 B                     35            30.0
2 City2 A                     20          -867. 
3 City2 A                     15          -299. 
4 City1 B                     19            29.2

打破城市功能

City1 <- function(data, city) {
  data %>%
    filter(City == city) %>%
    pull(ExpectedRevenue) %>%
    max() + 10 * rnorm(1)
}

City2 <- function(data, city) {
  data %>%
    filter(City == city) %>%
    pull(ExpectedRevenue) %>%
    max() - 1000 * rnorm(1)
}

set.seed(100)
zz %>%
  rowwise() %>%
  mutate(AdjustRevenue = case_when(City == 'City1' ~ City1(., City),
                                   City == 'City2' ~ City2(., City),
                                   TRUE ~ NA_real_))

【讨论】:

  • 感谢您的回答。不幸的是,每种城市类型的实际功能比我在这里展示的功能更复杂。在您的回答中,您是否能够调用不同的函数,而不是把它们写出来。特别是这里的行:mer + 10 * rnorm(1)。还是在使用case_when时无法正确调用自定义函数?
  • @Prometheus 可以调用单独的函数。第一个示例允许使用重复的代码,因此更容易创建/维护。如果它们是完全不同的函数,那么您可以使用第二个示例,以便它们是独立的。
猜你喜欢
  • 1970-01-01
  • 2018-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多