Изменить структуру данных (два кадра на один) - PullRequest
2 голосов
/ 05 июля 2019

У меня есть два data.frames (data1 и data2).

data1 <- data.frame(id = c(1,2,3),
                    var1 = c("x", "x", "x"),
                    var2 = c("y", "y", "y") )

data2 <- data.frame(id = c(1,2,3,4,5,6,7,8),
                    data1Id = c(1,1,2,2,2,3,3,3),
                    var3 = c(0, 3, 5, 2, 5, 2, 9, 8),
                    var4 = c(1, 6, 3, 6, 2, 8, 7, 5))

Для каждой записи в data1 есть несколько записей в data2. Обе таблицы связаны между собой переменной data1Id. Моя цель - иметь один единственный data.frame. Поэтому я хотел бы добавить столбцы от data2 до data1 и увеличить имена столбцов на 1 для каждой записи в data2.

В приведенном выше примере

id    var1    var2    var3_1   var3_2   var3_3    var4_1   var4_2   var4_3
----------------------------------------------------------------------------
1     x       y       0        3         NA       1        6        NA
2     x       y       5        2         5        3        6        2 
3     x       y       2        9         8        8        7        5

Может кто-нибудь дать мне подсказку, как этого добиться?

Ответы [ 3 ]

4 голосов
/ 05 июля 2019

Вы должны изменить свою data2, а затем присоединиться к data1:

library(tidyverse)

data2 %>%
  select(-id) %>%
  group_by(data1Id) %>%                            # for each data1Id
  mutate(indx = row_number()) %>%                  # create a row index (useful to reshape)
  ungroup() %>%
  gather(var, value, -data1Id, -indx) %>%          # reshape dataset
  unite(var, var, indx) %>%                        # combine those to columns to create new column names for reshaping
  spread(var, value) %>%                           # reshape again
  right_join(data1, by = c("data1Id" = "id")) %>%  # join to data1
  select(id = data1Id, var1, var2, everything())   # update column order

# # A tibble: 3 x 9
#      id var1  var2  var3_1 var3_2 var3_3 var4_1 var4_2 var4_3
#   <dbl> <fct> <fct>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
# 1     1 x     y          0      3     NA      1      6     NA
# 2     2 x     y          5      2      5      3      6      2
# 3     3 x     y          2      9      8      8      7      5
2 голосов
/ 05 июля 2019

Вот еще один tidyverse способ использования inner_join

library(tidyverse)

inner_join(data1, data2, by = c("id" = "data1Id")) %>%
   gather(key, value, -(1:3)) %>%
   filter(key != "id.y") %>%
   group_by(id) %>%
   mutate(key = paste(key, row_number(), sep = "_")) %>%
   spread(key, value)

# A tibble: 3 x 10
# Groups:   id [3]
#     id var1  var2  var3_1 var3_2 var3_3 var4_3 var4_4 var4_5 var4_6
#  <dbl> <fct> <fct>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
#1     1 x     y          0      3     NA      1      6     NA     NA
#2     2 x     y          5      2      5     NA      3      6      2
#3     3 x     y          2      9      8     NA      8      7      5

Вышеприведенный код запутывает имя столбца, которое можно изменить вручную позже или использовать метод ниже (как предложено @AntoniosK)

inner_join(data1, data2, by = c("id" = "data1Id")) %>%
   gather(key, value, -(1:3)) %>%
   filter(key != "id.y") %>%
   group_by(id, key) %>%
   mutate(key1 = paste(key, row_number(), sep = "_"))  %>%
   ungroup() %>%
   select(-key) %>%
   spread(key1, value)


# A tibble: 3 x 9
#     id var1  var2  var3_1 var3_2 var3_3 var4_1 var4_2 var4_3
#  <dbl> <fct> <fct>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
#1     1 x     y          0      3     NA      1      6     NA
#2     2 x     y          5      2      5      3      6      2
#3     3 x     y          2      9      8      8      7      5
1 голос
/ 05 июля 2019

Мы также можем использовать data.table объединений вместе с melt/dcast

library(data.table)
setDT(data1)[dcast(melt(setDT(data2)[, id := rowid(data1Id)], 
 id.var = c('id', 'data1Id'))[, variable := paste(variable, id, 
   sep="_")], data1Id ~ variable, value.var = 'value'), on = .(id = data1Id)]
#   id var1 var2 var3_1 var3_2 var3_3 var4_1 var4_2 var4_3
#1:  1    x    y      0      3     NA      1      6     NA
#2:  2    x    y      5      2      5      3      6      2
#3:  3    x    y      2      9      8      8      7      5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...