Сводная таблица

Вопросы по статистическому пакету R. Не обязательно гео.
Ответить
Аватара пользователя
VistaSV30
Активный участник
Сообщения: 185
Зарегистрирован: 02 июл 2018, 15:05
Репутация: 7
Откуда: Балашиха

Сводная таблица

Сообщение VistaSV30 » 19 сен 2020, 14:22

Добрый день!
Подскажите как в R делать сводные таблицы?
Допустим есть таблица:

Код: Выделить всё

Year <- rep(2018:2020, 3)
Name <- rep(LETTERS[1:3], each=3)
N <- sample(100:900, 9)
df <- data.frame(Year, Name, N)

  Year Name   N
1 2018    A 684
2 2019    A 359
3 2020    A 502
4 2018    B 589
5 2019    B 761
6 2020    B 207
7 2018    C 172
8 2019    C 863
9 2020    C 664
А надо переформатировать ее в сводную:

Код: Выделить всё

Name    Year
        2018 2019  2020
A       684   359   502   
B       589   761   207
C       172   863   664
Спасибо!
Природа не просто эксцентричнее, чем мы полагаем - она эксцентричнее, чем мы способны предположить. John Haldane

nickleb
Гуру
Сообщения: 964
Зарегистрирован: 22 май 2010, 20:20
Репутация: 154

Re: Сводная таблица

Сообщение nickleb » 19 сен 2020, 15:11

tidyr поновее инсталлируйте и через pivot_wider так :

Код: Выделить всё

library(tidyr)

Year <- rep(2018:2020, 3)
Name <- rep(LETTERS[1:3], each=3)
N <- sample(100:900, 9)
df <- data.frame(Year, Name, N, stringsAsFactors = FALSE)
str(df)

df_wider <- df %>% 
  pivot_wider(names_from = Year, values_from = N)

View(df_wider)
гляньте только - это ли Вам надо ! :)

nickleb
Гуру
Сообщения: 964
Зарегистрирован: 22 май 2010, 20:20
Репутация: 154

Re: Сводная таблица

Сообщение nickleb » 19 сен 2020, 15:24

... такое преобразование обычно называют от "длинного" формата к "широкому" ... "сводная" таблица - это, по-моему, несколько другое и подразумевает агрегирование ("типа" group by в SQL-терминологии...)

nickleb
Гуру
Сообщения: 964
Зарегистрирован: 22 май 2010, 20:20
Репутация: 154

Re: Сводная таблица

Сообщение nickleb » 19 сен 2020, 15:37

... о новом tidyr читайте на Хабр'е у Алексея Селезнёва https://habr.com/ru/post/444622/

Аватара пользователя
VistaSV30
Активный участник
Сообщения: 185
Зарегистрирован: 02 июл 2018, 15:05
Репутация: 7
Откуда: Балашиха

Re: Сводная таблица

Сообщение VistaSV30 » 19 сен 2020, 15:58

nickleb писал(а):
19 сен 2020, 15:24
... такое преобразование обычно называют от "длинного" формата к "широкому" ... "сводная" таблица - это, по-моему, несколько другое и подразумевает агрегирование ("типа" group by в SQL-терминологии...)
В MS Excel и Access такие таблицы называются "сводные".
Что поделаешь, у всех своя терминология, поэтому приходится делать примеры, того чего на самом деле хочется получить в итоге.

Еще раз спасибо за помощь!
Природа не просто эксцентричнее, чем мы полагаем - она эксцентричнее, чем мы способны предположить. John Haldane

gamm
Гуру
Сообщения: 4046
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1050
Ваше звание: программист
Откуда: Казань

Re: Сводная таблица

Сообщение gamm » 19 сен 2020, 16:56

то, что в примере, не имеет отношения к "сводной таблице", поскольку каждая пара ключей встречается ровно один раз. Это просто развернутая в линию таблица, для нее достаточно превратить ее в таблицу, см. скрипт ниже, последние строки.

В реальности эта "сводная таблица" называется многомерным кубом (в ней может быть больше 2 ключей), или "шахматкой". Некоторые пары ключей могут встречаться больше одного раза, некоторые - ни разу, и нужна функция агрегации (в примере ниже - сумма). Я уверен, что существует не один десяток пакетов с хитромудрыми функциями, которые это могут делать, однако с ними обычно те же проблемы, что и с ggplot2 - проще написать самому :mrgreen:

Ниже пример для суммы по всем парам ключей

Код: Выделить всё

set.seed(123)
Year <- sample(2018:2020, 15,replace=TRUE)
Name <- sample(LETTERS[1:3],15,replace=TRUE)
N <- sample(100:900, 15)
df <- data.frame(Year, Name, N)
df
   Year Name   N
1  2018    C 871
2  2020    A 821
3  2019    A 651
4  2020    A 734
5  2020    C 119
6  2018    C 480
7  2019    C 702
8  2020    B 271
9  2019    C 352
10 2019    B 283
11 2020    C 212
12 2019    B 427
13 2020    B 426
14 2019    A 390
15 2018    A 219

Year.list=sort(unique(df$Year))
Name.list=sort(unique(df$Name))
tmp=expand.grid(Year.list,Name.list)
all.key=sprintf("%d-%s",tmp[,1],tmp[,2])
all.val=rep(0,length(all.key))
key=sprintf("%d-%s",df$Year,df$Name)
val=tapply(df$N,key,sum)
val.key=attr(val, "dimnames")[[1]]
key.pos=match(val.key,all.key)
all.val[key.pos]=val
val.mtr=matrix(all.val,ncol=length(Year.list),nrow=length(Name.list),byrow=TRUE)
colnames(val.mtr)=Year.list
rownames(val.mtr)=Name.list
val.mtr
  2018 2019 2020
A  219 1041 1555
B    0  710  697
C 1351 1054  331

nplatonov
Интересующийся
Сообщения: 25
Зарегистрирован: 07 фев 2012, 12:00
Репутация: 20

Re: Сводная таблица

Сообщение nplatonov » 20 сен 2020, 07:58

Код: Выделить всё

stats::reshape(df,timevar="Year",idvar="Name",direction="wide")

Ответить

Вернуться в «R»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей