Rbind для таблиц с повторяющимися именами строк

У меня есть две таблицы, которые я хотел бы объединить для создания сводной таблицы.

df1 <- data.frame(median=c(151, 98, 125, 47),
                             Q25=c(148, 90, 120, 44),
                             Q75=c(158, 104, 132, 53),
                  pass_or_fail=c('pass')
                             )
row.names(df1)<-c("param1", "param2", "param3", "param4")

df2 <- data.frame(median=c(148, 95, 135, 40),
                             Q25=c(140, 88, 130, 35),
                             Q75=c(150, 100, 141, 45),
                  pass_or_fail=c('fail')
                             )
row.names(df2)<-c("param1", "param2", "param3", "param4")



rbind(df1, df2)

Результат, который я ищу, показан ниже, где имена строк являются общими для двух фреймов данных, столбцы сгруппированы по «пройдено» или «не пройдено», а значение отображается как медиана с IQR в скобках.

Результатом rbind являются измененные имена строк, поскольку повторяющиеся имена не допускаются. Мне интересно, как я могу решить проблему переименования имен строк и можно ли отобразить IQR в скобках с помощью kable или другой функции.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
65
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий
library(dplyr)
library(tibble)
library(tidyr)

bind_rows(rownames_to_column(df1), 
          rownames_to_column(df2)) %>% 
  mutate(stat = paste0(median, " (", Q25, "-", Q75, ")"), .keep = "unused") %>% 
  pivot_wider(names_from = pass_or_fail, values_from = stat) %>% 
  column_to_rownames()

#>                 pass          fail
#> param1 151 (148-158) 148 (140-150)
#> param2   98 (90-104)   95 (88-100)
#> param3 125 (120-132) 135 (130-141)
#> param4    47 (44-53)    40 (35-45)

Created on 2024-07-07 with reprex v2.0.2

Немного cbind забавы: использование пробела df1[0] для сохранения имен строк:

cbind(
    df1[0],
    pass = with(df1,
                paste0(median, " (", Q25, "-", Q75, ")")),
    fail = with(df2[rownames(df1),],
                paste0(median, " (", Q25, "-", Q75, ")"))
)
#                pass          fail
#param1 151 (148-158) 148 (140-150)
#param2   98 (90-104)   95 (88-100)
#param3 125 (120-132) 135 (130-141)
#param4    47 (44-53)    40 (35-45)

Использование sprintf с do.call.

> sapply(list(df1[-4], df2[-4]), \(x) do.call('sprintf', c('%s (%s-%s)', x))) |> 
+   `dimnames<-`(list(rownames(df1[-4]), unique(c(df1[, 4], df2[, 4])))) |> 
+   as.data.frame()
                pass          fail
param1 151 (148-158) 148 (140-150)
param2   98 (90-104)   95 (88-100)
param3 125 (120-132) 135 (130-141)
param4    47 (44-53)    40 (35-45)

Данные:

> dput(df1)
structure(list(median = c(151, 98, 125, 47), Q25 = c(148, 90, 
120, 44), Q75 = c(158, 104, 132, 53), pass_or_fail = c("pass", 
"pass", "pass", "pass")), class = "data.frame", row.names = c("param1", 
"param2", "param3", "param4"))
> dput(df2)
structure(list(median = c(148, 95, 135, 40), Q25 = c(140, 88, 
130, 35), Q75 = c(150, 100, 141, 45), pass_or_fail = c("fail", 
"fail", "fail", "fail")), class = "data.frame", row.names = c("param1", 
"param2", "param3", "param4"))

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

Как пройти и создать сумму ролловера в Python?
Как я могу использовать groupby, чтобы каждая группа группировалась с предыдущей перекрывающейся группой?
Нарезка нескольких фрагментов в фрейме данных Polars
Вычитание серии панд из всех элементов другой серии панд с общим идентификатором
Как идиоматически объединить кадры данных с перекрывающимися строками и столбцами в Polars 1.0?
Python Pandas: обновление значений параметров последних дат с помощью простой динамики, сгруппированной по идентификатору
Оптимизация обработки DataFrame для интервалов входа пользователей в Pandas
Суммирование значений на основе диапазонов дат в DataFrame с использованием Polars
При циклическом просмотре кадра данных в поисках строковых значений. Как распечатать строки без дублирования, если поисковый запрос встречается несколько раз?
Как применить результат функции Python к новому столбцу в фрейме данных Polars