Изменить форму при объединении нескольких фреймов данных - PullRequest
0 голосов
/ 01 мая 2018

У меня есть несколько фреймов данных в одном формате, например:

price <- data.frame(Year= c(2001, 2002, 2003),
                    A=c(1,2,3),B=c(2,3,4), C=c(4,5,6))
size <- data.frame(Year= c(2001, 2002, 2003), 
                   A=c(1,2,3),B=c(2,3,4), C=c(4,5,6))
performance <- data.frame(Year= c(2001, 2002, 2003),
                          A=c(1,2,3),B=c(2,3,4), C=c(4,5,6))

> price
  Year A B C
1 2001 1 2 4
2 2002 2 3 5
3 2003 3 4 6

> size
  Year A B C
1 2001 1 2 4
2 2002 2 3 5
3 2003 3 4 6

> performance
  Year A B C
1 2001 1 2 4
2 2002 2 3 5
3 2003 3 4 6

и я хочу объединить эти фреймы данных, но результат находится в другой форме, желаемый результат выглядит так:

> df
  name Year price size performance
1    A 2001     1    1           1
2    A 2002     2    2           2
3    A 2003     3    3           3
4    B 2001     2    2           2
5    B 2002     3    3           3
6    B 2003     4    4           4
7    C 2001     3    3           3
8    C 2002     4    4           4
9    C 2003     5    5           5

, который упорядочивает данные в порядке имен, а затем упорядоченную дату. Поскольку у меня более 2000 имен и 180 дат в каждом из 20 фреймов данных, слишком сложно отсортировать их, просто вписав определенное имя.

Ответы [ 5 ]

0 голосов
/ 02 мая 2018

Чтобы округлить это, вот базовый ответ R без пакета.

# gather the data.frames into a list
myList <- mget(ls())

Обратите внимание, что три data.frames являются единственными объектами в моей среде.

# get the final data.frame
Reduce(merge, 
       Map(function(x, y) setNames(cbind(x[1], stack(x[-1])), c("Year", y, "ID")),
           myList, names(myList)))

Возвращает

  Year ID performance price size
1 2001  A           1     1    1
2 2001  B           2     2    2
3 2001  C           4     4    4
4 2002  A           2     2    2
5 2002  B           3     3    3
6 2002  C           5     5    5
7 2003  A           3     3    3
8 2003  B           4     4    4
9 2003  C           6     6    6
0 голосов
/ 02 мая 2018

вы можете использовать data.table

library(data.table)
a=list(price=price,size=size,performance=performance)
dcast(melt(rbindlist(a,T,idcol = "name"),1:2),variable+Year~name)
   variable Year performance price size
1:        A 2001           1     1    1
2:        A 2002           2     2    2
3:        A 2003           3     3    3
4:        B 2001           2     2    2
5:        B 2002           3     3    3
6:        B 2003           4     4    4
7:        C 2001           4     4    4
8:        C 2002           5     5    5
9:        C 2003           6     6    6
0 голосов
/ 02 мая 2018

Мы можем объединять кадры данных, собирать и распространять объединенные кадры данных.

library(tidyverse)

dat <- list(price, size, performance) %>%
  setNames(c("price", "size", "performance")) %>%
  bind_rows(.id = "type") %>%
  gather(name, value, A:C) %>%
  spread(type, value) %>%
  arrange(name, Year)

dat
#   Year name performance price size
# 1 2001    A           1     1    1
# 2 2002    A           2     2    2
# 3 2003    A           3     3    3
# 4 2001    B           2     2    2
# 5 2002    B           3     3    3
# 6 2003    B           4     4    4
# 7 2001    C           4     4    4
# 8 2002    C           5     5    5
# 9 2003    C           6     6    6
0 голосов
/ 02 мая 2018

dplyr::bind_rows очень удобно в таких ситуациях. Решение может быть как:

library(tidyverse)

bind_rows(list(price = price, size = size, performance = performance), .id="Type") %>%
  gather(Key, Value, - Type, -Year) %>%
  spread(Type, Value)

#   Year Key performance price size
# 1 2001   A           1     1    1
# 2 2001   B           2     2    2
# 3 2001   C           4     4    4
# 4 2002   A           2     2    2
# 5 2002   B           3     3    3
# 6 2002   C           5     5    5
# 7 2003   A           3     3    3
# 8 2003   B           4     4    4
# 9 2003   C           6     6    6

Приведенное выше решение очень похоже на решение @www. Это просто избегает использования setNames

0 голосов
/ 01 мая 2018

Вам необходимо преобразовать ваши фреймы данных в длинный формат, а затем объединить их вместе

library(tidyverse)

price_long <- price %>% gather(key, value = "price", -Year)
size_long <- size %>% gather(key, value = "size", -Year)
performance_long <- performance %>% gather(key, value = "performance", -Year)

price_long %>% 
  left_join(size_long) %>% 
  left_join(performance_long)

Joining, by = c("Year", "key")
Joining, by = c("Year", "key")

  Year key price size performance
1 2001   A     1    1           1
2 2002   A     2    2           2
3 2003   A     3    3           3
4 2001   B     2    2           2
5 2002   B     3    3           3
6 2003   B     4    4           4
7 2001   C     4    4           4
8 2002   C     5    5           5
9 2003   C     6    6           6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...