Используйте scale_x_continuous с функцией labeller, которая также принимает фрейм данных в качестве аргумента, а также разрывы по умолчанию - PullRequest
1 голос
/ 04 августа 2020

Вот блок кода:

# scale the log of price per group (cut)
my_diamonds <- diamonds %>% 
  mutate(log_price = log(price)) %>% 
  group_by(cut) %>% 
  mutate(scaled_log_price = scale(log_price) %>% as.numeric) %>% # scale within each group as opposed to overall
  nest() %>% 
  mutate(mean_log_price = map_dbl(data, ~ .x$log_price %>% mean)) %>% 
  mutate(sd_log_price = map_dbl(data, ~ .x$log_price %>% sd)) %>% 
  unnest %>% 
  select(cut, price, price_scaled:sd_log_price) %>% 
  ungroup


# for each cut, find the back transformed actual values (exp) of each unit of zscore between -3:3
for (i in -3:3) {
    my_diamonds <- my_diamonds %>%
      mutate(!! paste0('mean_', ifelse(i < 0 , 'less_', 'plus_'), abs(i), 'z') := map2(.x = mean_log_price, .y = sd_log_price, ~ (.x + (i * .y)) %>% exp) %>% unlist)
}

my_diamonds_split <- my_diamonds %>% group_split(cut)
split_names <- my_diamonds %>% mutate(cut = as.character(cut)) %>% group_keys(cut) %>% pull(cut)
names(my_diamonds_split) <- split_names

Теперь у меня есть переменная my_diamonds_split, которая представляет собой список фреймов данных. Я хотел бы l oop поверх этих фреймов данных и каждый раз создавать новый ggplot.

Я могу использовать настраиваемую функцию этикетировщика с одним df, но я не знаю, как это сделать в al oop:

labeller <- function(x) {
  paste0(x,"\n",  scales::dollar(sd(ex_df$price) * x + mean(ex_df$price)))
}

ex_df <- my_diamonds_split$Ideal
ex_df %>% 
  ggplot(aes(x = scaled_log_price)) +
  geom_density() +
  scale_x_continuous(label = labeller, limits = c(-3, 3))

Это создает сюжет для «Идеальной» огранки бриллиантов. Я также получаю две точки данных на оси x, значения zscore на -2, 0 и 2, а также необработанные значения в долларах 3,8, 3,9 и 11,8 тыс.

введите описание изображения здесь

Когда я определяю функцию labeller, я должен указать df для масштабирования. Вместо этого попробовал разместить точку вместо my_df, надеясь, что на каждой итерации ggplot будет получать значение df на любой итерации:

labeller <- function(x) {
  paste0(x,"\n",  scales::dollar(sd(.$price) * x + mean(.$price)))
}

ex_df <- my_diamonds_split$Ideal
ex_df %>% 
  ggplot(aes(x = scaled_log_price)) +
  geom_density() +
  scale_x_continuous(label = labeller, limits = c(-3, 3))

Возвращает:

Ошибка в .data.frame (x): объект '.' не найдено

Затем я попытался написать функцию, которая принимает аргумент для масштабирования df с помощью:

labeller <- function(x, df) {
  paste0(x,"\n",  scales::dollar(sd(df$price) * x + mean(df$price)))
}

ex_df <- my_diamonds_split$Ideal
ex_df %>% 
  ggplot(aes(x = scaled_log_price)) +
  geom_density() +
  scale_x_continuous(label = labeller(df = ex_df), limits = c(-3, 3)) # because when it comes to running in real life, I will try something like labeller(df = my_diamonds_split[[i]])

Ошибка в paste0 (x, "\ n" , scale :: dollar (sd (df $ price) * x + mean (df $ price))): аргумент «x» отсутствует, значение по умолчанию не задано

Принимая во внимание, что масштабирование должно быть выполнено за итерацию, как я могу l oop over my_diamonds_split, и на каждой итерации генерировать ggplot, как указано выше?

labeller <- function(x) {
# how can I make df variable
  paste0(x,"\n",  scales::dollar(sd(df$price) * x + mean(df$price)))
}
for (i in split_names) {
  my_diamonds_split[[i]] %>% 
    ggplot(aes(x = scaled_log_price)) +
    geom_density() +
    scale_x_continuous(label = labeller, # <--- here, labeller must be defined with df$price except that will difer on each iteration
                       limits = c(-3, 3))
}

1 Ответ

2 голосов
/ 05 августа 2020

Есть хитрый способ получить такой результат в фасетах. По сути, после преобразования в z-оценки вы добавляете разные суммы (скажем, кратные 1000) к z-оценкам каждой группы. Затем вы устанавливаете все разрывы для этого набора точек и маркируете их предварительно рассчитанными метками.

Created on 2020-08-04 by the пакет REPEX (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...