Отредактировано, чтобы поставить reprex в ответ на комментарии.
Я читаю общедоступные данные о температуре в 58 округах Калифорнии за несколько лет. Я хотел бы создать сводку, среднесуточное среднее значение по штату, и поместить эти средние значения в новые строки поверх фрейма данных с данными округа за один последовательный шаг.
Теперь я делаю это в три этапа: (1) считываю данные округа, (2) создаю средства отдельно и (3) строю привязку вновь созданных средств к данным.
Вот репрекс:
#### Reprex ####
library(tidyverse)
df1 <-
data.frame(
name = toupper(c(rep(letters[1:5], each=5))),
x = as.character(c(rnorm(25, 55, 10)))
)
df2 <- df1 |>
group_by(name) |>
mutate(x = mean(as.numeric(x), narm = TRUE)) |>
ungroup() |>
select(name, x) |>
unique() |>
mutate(name = "Z")
df <- rbind(df1, df2)
Вот что я пробовал до сих пор, но безрезультатно. Оба выдают сообщение об ошибке: Error in UseMethod("summarise") : no applicable method for 'summarise' applied to an object of class "c('double', 'numeric')":
#Test 1
df <-
data.frame(
name = toupper(c(rep(letters[1:5], each=5))),
x = as.character(c(rnorm(25, 55, 10)))
) |>
group_by(name) |>
select(name, x) |>
do(bind_rows(., data.frame(name = "Z",
mutate(x = mean(as.numeric(.$x), narm = TRUE))))) |>
ungroup()
#Test 2
df <-
df <-
data.frame(
name = toupper(c(rep(letters[1:5], each=5))),
x = as.character(c(rnorm(25, 55, 10)))
) |>
group_by(name) |>
select(name, x) |>
do(bind_rows(., data.frame(name = "Z",
mutate(x = summarize(mean(as.numeric(.$x), narm = TRUE)))))) |>
ungroup()
Буду признателен за любую оказанную помощь.
Пакет EpiNOAA недоступен в CRAN и имеет определенные зависимости, которые затрудняют установку из исходного кода. Пожалуйста, предоставьте образец df, отредактировав свое сообщение, включив в него вывод dput(df[1:00, ]) (или аналогичного).
Интересно, подействует ли что-то подобное на ваши данные? mtcars %>% rownames_to_column() %>% { bind_rows(., summarize(., across(2:12, mean)) %>% mutate(rowname = "State avg")) }
Большое спасибо за комментарии. Я думал, что, поскольку и климатические данные NClimGrid, и пакет EpiNOAA R доступны публично, мой пример можно воспроизвести. Хотя это, конечно, не было минимальным! :) Это reprex работает?
Это намного лучше, спасибо! Даже когда данные доступны, очень приятно включить их в вопрос, если они не встроены. У большинства людей пакет EpiNOAA не установлен, и похоже, что его даже нет в CRAN. Так что на самом деле это устанавливает довольно высокую планку для того, чтобы люди начали вам помогать. После ваших изменений полоса устанавливается на копирование/вставку, что намного удобнее как для людей, желающих ответить на ваш вопрос сейчас, так и для будущих читателей с аналогичными проблемами.
Понял. Да, я определенно хочу, чтобы людям было как можно проще помогать. Это обычная вежливость. Возможно, я даже получу положительный голос!
Спасибо, @JonSpring! Ваш код работает хорошо и имеет дополнительное преимущество — компактность. Мне удалось изменить его, чтобы включить group_by в набор данных mtcars. Все еще работаю над его модификацией для своих первоначальных целей (климатические данные).





Базовый канал R не позволяет вам использовать объект, который он передает по конвейеру, более одного раза — и здесь необходимо дважды: один раз для добавления и один раз для получения средства — но вы можете обойти это, передав его в анонимную функцию: так. (Обратите внимание, что я уменьшил размер ваших данных до 3 групп по 3, чтобы их было легче увидеть и установить начальное значение, чтобы генерация случайных чисел была полностью воспроизводимой.)
library(dplyr)
set.seed(47)
df <-
data.frame(
name = toupper(c(rep(letters[1:3], each=3))),
x = as.character(c(rnorm(9, 55, 10)))
) |>
mutate(x = as.numeric(x)) |>
(
\(dd) bind_rows(dd, summarize(dd, x = mean(x), .by = name))
)()
df
# name x
# 1 A 74.94696
# 2 A 62.11143
# 3 A 56.85405
# 4 B 52.18235
# 5 B 56.08776
# 6 B 44.14263
# 7 C 45.14518
# 8 C 55.15131
# 9 C 52.47954
# 10 A 64.63748
# 11 B 50.80424
# 12 C 50.92534
Мне это не очень нравится, стилистически я бы сделал это в два этапа: 1 — прочитать и очистить данные, 2 — вычислить и добавить. Заполнитель базового канала R _ требует именованный аргумент, которого bind_rows нет, поэтому нам все еще нужна анонимная функция, но я все равно предпочитаю этот способ:
## step 1
df <-
data.frame(
name = toupper(c(rep(letters[1:3], each=3))),
x = as.character(c(rnorm(9, 55, 10)))
) |>
mutate(x = as.numeric(x))
## step 2
df = df |>
summarize(x = mean(x), .by = name) |>
(\(x) bind_rows(df, x))()
Если вас не беспокоит трубка magrittr, вы можете упростить Шаг 2 до следующего:
## alternate step 2
df = df |>
summarize(x = mean(x), .by = name) %>%
bind_rows(df, .)
Предоставить представление о данных, в идеале от 10 до 20 строк минимальный воспроизводимый пример всегда полезно, чтобы лучше понять, что происходит. Я предполагаю, что
bind_rowsне любит, когда его помещают в (замененный)do.