R предоставляет аргументы при использовании case_when (R векторизация) - PullRequest
3 голосов
/ 17 июня 2020

Это следующий вопрос к вопросу, который я задавал ранее ( R применяет несколько функций, когда присутствует большое количество категорий / типов, используя case_when (R векторизация) ). К сожалению, я не смог разобраться в проблеме. Я думаю, что, возможно, сузил источник проблемы и хотел проверить, может ли кто-то с более глубоким пониманием, чем я, помочь мне найти решение.

Предположим, у меня есть следующий набор данных:

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. Мой исходный набор данных содержит около 200 тысяч наблюдений с несколькими предприятиями и около 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, скорректированные значения такие же . Вместо этого я ожидал получить разные значения для каждого наблюдения (поскольку я добавляю или удаляю какое-то случайное число для каждого наблюдения; или, по крайней мере, намеревался). Следуя ответу Мартина Гала на мой предыдущий вопрос ({ ссылка }), я подозреваю, что это связано с неправильным вызовом второго аргумента моих функций City1 и City2 на последнем этапе. Однако я несколько заблудился, пытаясь понять, почему и что делать, чтобы это исправить.

Было бы очень полезно, если бы кто-нибудь мог указать, почему это происходит и как исправить эту ошибку. Заранее спасибо!

PS Я также открыт для других векторизованных решений. Я относительно новичок в векторизации и не имею в ней большого опыта и буду признателен за любые предложения.

1 Ответ

1 голос
/ 17 июня 2020

Преобразовал функции 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_))
...