У меня есть набор данных, который я хочу group_by() и создать гистограмму для каждой группы. Мой текущий код выглядит следующим образом:
df %>%
group_by(x2) %>%
with(hist(x3,breaks = 50))
Однако это генерирует единую гистограмму всего x3, а не несколько фрагментов x3, вот некоторые примеры данных.
df = data.frame(x1 = rep(c(1998,1999,2000),9),
x2 = rep(c(1,1,1,2,2,2,3,3,3),3),
x3 = rnorm(27,.5))
желаемый результат:
фактический результат:
?do должно помочь
hist принимает только столбец данных, игнорируя вашу группировку. Вместо этого используйте ggplot или выполните
@infominer OP передает на with, который принимает полный фрейм данных. Проблема в том, что внешние функции dplyr игнорируют группировку --- это верно как для ggplot, так и для with или hist.
@Грегор, ты тоже. Заметил это после того, как написал свой комментарий. с ggplot им придется фасетировать или иметь возможность использовать заливку для окрашивания полос.





Я думаю, что пришло время перейти к ggplot, например:
library(tidyverse)
df %>%
ggplot(aes(x = x3)) +
geom_histogram(bins = 50) +
facet_wrap(~x2) # optional: use argument "ncols = 1"
Может быть, я что-то упустил, OP сделал включает образцы данных
facet_grid(rows = vars(x2)) больше соответствует ожидаемому результату OP. И в коде создания данных OP я добавил ноль к каждому вектору-столбцу.
Однако я не вижу ничего в истории редактирования поста. Не имейте в виду, что это ошибка с вашим сообщением
Мой комментарий о do устарел, наверное. ?do указывает на текущий ?group_walk:
df %>%
group_by(x2) %>%
group_walk(~ hist(.x$x3))
В версиях dplyr < 0.8.0 group_walk нет, поэтому можно использовать do:
df %>%
group_by(x2) %>%
do(h = hist(.$x3))
Предполагая, что вам нужны только побочные эффекты hist (печатная гистограмма), а не возвращаемые значения, вы можете добавить %>% invisible() в конец цепочки, чтобы не печатать результирующую табличку.
Откуда group_walk? sos::findFn('group_walk') найдено 0 совпадений.
Это функция dplyr, возможно, вам придется обновить ее до самой последней версии пакета.
@RuiBarradas Я думаю, это было новым в dplyr 0.8.0. Я добавлю версию do для обратной совместимости.
Спасибо! Это делает именно то, что я хотел. можно ли передать другие аргументы в вызове group_walk()? Например, изменить основной заголовок на переменную группировки? Что-то вроде `main = .x$x2' (этот синтаксис не работает что-то о "неизвестном или неинициализированном столбце") -редактировать- разобрался, нужно инициализировать столбец с .y$x2
Спасибо. Тем временем я обновил пакет dplyr.
Вы можете использовать команду split.data.frame для разделения данных на основе категорий, после чего вы запускаете команду hist в списке кадров данных.
list_df <- split.data.frame(df, f= df$x2)
par(mfrow = c(round(length(list_df), 0), 1))
for( lnam in names(list_df)){
hist(list_df[[lnam]][, "x3"])
}
split — это функция S3, поэтому, если вы просто используете split(df, f = df$x2), она отправит split.data.frame для вас.
Мне очень нравится ответ @Грегора с group_walk, но он все еще указан как экспериментальный в dplyr v0.8.0.1. Если вы хотите избежать работы с функциями, которые впоследствии могут сломаться, я бы использовал базу split, а затем purrr::walk. Я использую walk и plot, чтобы избежать распечатки всего текста, который дает hist.
library(dplyr)
library(purrr)
df %>%
split(.$x2) %>%
walk(~hist(.$x3) %>% plot())
Хороший ответ! Рассматривайте %>% invisible как более прямой/общий способ избежать вывода текста.
Базовые функции R, такие как
hist, не заботятся о dplyrgroup_by.