#r #dataframe #dplyr #pivot
#r #фрейм данных #dplyr #сводная
Вопрос:
Я новичок в R, поэтому прошу прощения, если это простой вопрос. Я часто использую Excel для создания таблиц с «двойными записями». Вероятно, название «двойная таблица» не самое точное, но я бы не знал, как описать это иначе. Я в основном начинаю с больших таблиц, а затем создаю новую, где я усредняю группировку данных по двум столбцам, а затем отображаю ее в виде матрицы. Я поделюсь с вами совершенно функциональным примером R, который я сам закодировал. Мой вопрос: есть ли более простой / лучший способ сделать это? Это мой рабочий код:
require(dplyr)
df <- mtcars
output_var <- 'disp'
rows_var <- 'cyl'
col_var <- 'am'
output_name <- paste0("Avg. ",output_var)
one_way_table <- df %>%
group_by(eval(parse(text=rows_var)), eval(parse(text=col_var)) ) %>%
summarise(output=mean( eval(parse(text=output_var)) ))
one_way_table <- data.frame(one_way_table, check.rows = F, check.names = F, stringsAsFactors = F)
colnames(one_way_table) <- c(rows_var, col_var, output_name)
unique_row_items <- unique(one_way_table[,rows_var])
unique_col_items <- unique(one_way_table[,col_var])
x_rows <- rep(unique_row_items, length(unique_col_items))
y_cols <- rep(unique_col_items, length(unique_row_items))
new_df <- data.frame(x = x_rows, y = y_cols, check.rows = F, check.names = F, stringsAsFactors = F)
colnames(new_df) <- c(rows_var, col_var)
new_df <- base::merge(new_df, one_way_table, by = c(rows_var, col_var), all.x=T)
m <- matrix(new_df[, output_name], ncol= length(unique(new_df[,col_var])) )
df_matrix <- data.frame(m, check.rows = F, check.names = F, stringsAsFactors = F)
Возможно, есть более эффективный способ сделать это.
Обратите внимание, что, поскольку это будет закодировано внутри функции, мне пришлось использовать имена переменных, которые определяют, какие столбцы я хочу использовать для анализа.
Спасибо
Ответ №1:
Возможное решение вашей проблемы может быть получено из tidyverse
. Вот пример изменения формы ваших данных и агрегирования с помощью mean:
library(tidyverse)
#Data
df <- mtcars
#Code
df %>% pivot_longer(cols = -c(cyl,am)) %>% filter(name=='disp') %>%
group_by(cyl,am) %>% summarise(Mean=mean(value)) %>%
pivot_wider(names_from = am,values_from=Mean)
Вывод:
# A tibble: 3 x 3
# Groups: cyl [3]
cyl `0` `1`
<dbl> <dbl> <dbl>
1 4 136. 93.6
2 6 205. 155
3 8 358. 326
Которая близка к df_matrix
окончательному выводу вашего кода.
Ответ №2:
Если нам нужно выполнить поворот, это можно сделать более простым способом. Мы select
выбираем интересующие столбцы и используем их pivot_wider
с values_fn
указанием, как mean
будет применяться к столбцам, выбранным на values_from
library(dplyr)
library(tidyr)
mtcars %>%
select(cyl, am, disp) %>%
pivot_wider(names_from = am, values_from = disp, values_fn = mean)
# A tibble: 3 x 3
# cyl `1` `0`
# <dbl> <dbl> <dbl>
#1 6 155 205.
#2 4 93.6 136.
#3 8 326 358.