Как суммировать данные и привязать новые строки к существующему фрейму данных?

Отредактировано, чтобы поставить 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()

Буду признателен за любую оказанную помощь.

Предоставить представление о данных, в идеале от 10 до 20 строк минимальный воспроизводимый пример всегда полезно, чтобы лучше понять, что происходит. Я предполагаю, что bind_rows не любит, когда его помещают в (замененный) do.

Andre Wildberg 23.03.2024 13:40

Пакет EpiNOAA недоступен в CRAN и имеет определенные зависимости, которые затрудняют установку из исходного кода. Пожалуйста, предоставьте образец df, отредактировав свое сообщение, включив в него вывод dput(df[1:00, ]) (или аналогичного).

jdobres 23.03.2024 15:00

Интересно, подействует ли что-то подобное на ваши данные? mtcars %>% rownames_to_column() %>% { bind_rows(., summarize(., across(2:12, mean)) %>% mutate(rowname = "State avg")) }

Jon Spring 23.03.2024 17:17

Большое спасибо за комментарии. Я думал, что, поскольку и климатические данные NClimGrid, и пакет EpiNOAA R доступны публично, мой пример можно воспроизвести. Хотя это, конечно, не было минимальным! :) Это reprex работает?

David Crow 27.03.2024 02:02

Это намного лучше, спасибо! Даже когда данные доступны, очень приятно включить их в вопрос, если они не встроены. У большинства людей пакет EpiNOAA не установлен, и похоже, что его даже нет в CRAN. Так что на самом деле это устанавливает довольно высокую планку для того, чтобы люди начали вам помогать. После ваших изменений полоса устанавливается на копирование/вставку, что намного удобнее как для людей, желающих ответить на ваш вопрос сейчас, так и для будущих читателей с аналогичными проблемами.

Gregor Thomas 27.03.2024 02:13

Понял. Да, я определенно хочу, чтобы людям было как можно проще помогать. Это обычная вежливость. Возможно, я даже получу положительный голос!

David Crow 27.03.2024 02:20

Спасибо, @JonSpring! Ваш код работает хорошо и имеет дополнительное преимущество — компактность. Мне удалось изменить его, чтобы включить group_by в набор данных mtcars. Все еще работаю над его модификацией для своих первоначальных целей (климатические данные).

David Crow 28.03.2024 22:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Базовый канал 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, .)

Другие вопросы по теме