Создайте попарно data.frame из всех комбинаций двух data.frame с разным количеством строк - PullRequest
1 голос
/ 10 января 2020

У меня есть кадры данных a и b, которые я хочу объединить в окончательный кадр данных c

a <- data.frame(city=c("a","b","c"),detail=c(1,2,3))

b <- data.frame(city=c("x","y"),detail=c(5,6))

кадр данных c должен выглядеть как

  city.a detail.a city.b detail.b
1      a        1      x        5
2      a        1      y        6
3      b        2      x        5
4      b        2      y        6
5      c        3      x        5
6      c        3      y        6

Я думаю, я мог бы использовать пересечение от tidyr, но для crossing(a,b) я получаю:

error: Column names `city`, `detail` must not be duplicated.
Use .name_repair to specify repair.

Ответы [ 3 ]

2 голосов
/ 10 января 2020

Да, crossing - правильная функция, но поскольку в сообщении об ошибке указывается, что имена столбцов не должны дублироваться, попробуйте изменить имена столбцов

names(a) <- paste0(names(a), ".a")
names(b) <- paste0(names(b), ".b")
tidyr::crossing(a, b)

#  city.a detail.a city.b detail.b
#  <fct>     <dbl> <fct>     <dbl>
#1 a             1 x             5
#2 a             1 y             6
#3 b             2 x             5
#4 b             2 y             6
#5 c             3 x             5
#6 c             3 y             6

crossing - это оболочка над expand_grid так что после исправления имен вы также можете использовать его напрямую.

tidyr::expand_grid(a, b)
1 голос
/ 10 января 2020

С base R мы можем использовать merge

merge(setNames(a, paste0(names(a), ".a")), b)
#   city.a detail.a city detail
#1      a        1    x      5
#2      b        2    x      5
#3      c        3    x      5
#4      a        1    y      6
#5      b        2    y      6
#6      c        3    y      6
1 голос
/ 10 января 2020

Вот базовое решение R с использованием rep() + cbind(), которое дает дублированные имена столбцов:

C <- `row.names<-`(cbind(a[rep(seq(nrow(a)),each = nrow(b)),],b),NULL)

, такие что

> C
  city detail city detail
1    a      1    x      5
2    a      1    y      6
3    b      2    x      5
4    b      2    y      6
5    c      3    x      5
6    c      3    y      6

Или получить фрейм данных с разными именами столбцов, используя data.frame():

C <- data.frame(a[rep(seq(nrow(a)),each = nrow(b)),],b,row.names = NULL)

, такой что

> C
  city detail city.1 detail.1
1    a      1      x        5
2    a      1      y        6
3    b      2      x        5
4    b      2      y        6
5    c      3      x        5
6    c      3      y        6
...