Комбинация значений векторов с одинаковыми позиционными индексами в R - PullRequest
2 голосов
/ 13 февраля 2020

Предполагая, что у нас есть следующие упрощенные векторы (в действительности они содержат гораздо больше значений):

n <- c(1,2)
x <- c(4,5,6) 
y <- c(7,8,9)

#to get all possible combinations, we can use expand.grid 
df <- expand.grid(n=n,
                  x=x,
                  y=y
)

> df
   n x y
   1 4 7
   2 4 7
   1 5 7
   2 5 7
   1 6 7
   2 6 7
   1 4 8
   2 4 8
   1 5 8
   2 5 8
   1 6 8
   2 6 8
   1 4 9
   2 4 9
   1 5 9
   2 5 9
   1 6 9
   2 6 9

Однако я бы хотел векторы x , y иметь комбинацию, в которой рассматриваются только элементы с одинаковыми значениями индекса, т.е. (x1, y1), (x2, y2), (x3, y3), но НЕ (x1, y2), (x1, y3) и т. д. c. в то время как вектор n все еще используется как обычно (все его элементы «соединены» с результатом комбинации x и y).

Другими словами, я хотел бы получить следующий df :

   n x y
   1 4 7
   2 4 7
   1 5 8
   2 5 8
   1 6 9
   2 6 9

если бы n вектор имел 3 элемента, т.е. n <- (1, 2, 3), то мы бы получили: </p>

   n x y
   1 4 7
   2 4 7
   3 4 7
   1 5 8
   2 5 8
   3 5 8
   1 6 9
   2 6 9
   3 6 9

Ответы [ 4 ]

2 голосов
/ 13 февраля 2020

Вы можете объединить список пар, которые должны быть вместе, и затем использовать его в expand.grid

expand.grid(n, Map(c, x, y)) %>% tidyr::unnest_wider(Var2)

Или мы также можем использовать crossing, используя те же логики c.

library(tidyverse)

crossing(n, x = map2(x, y, c)) %>%
  unnest_wider(x) %>%
  rename_at(-1, ~c("x", "y"))

#      n     x     y
#  <dbl> <dbl> <dbl>
#1     1     4     7
#2     1     5     8
#3     1     6     9
#4     2     4     7
#5     2     5     8
#6     2     6     9
1 голос
/ 13 февраля 2020

Один из вариантов - вставить вместе x и y, а затем использовать расширенную сетку и отделить столбцы, используя отдельную функцию из пакета tidyr.

library(dplyr) #for pipe
library(tidyr) #for separate

n <- c(1,2)
x <- c(4,5,6) 
y <- c(7,8,9)
z <- paste(x, y, sep = "-")

expand.grid(n = n, xy = z) %>% 
  separate(xy, sep = "-", into = c("x", "y")) %>%
  mutate(x = as.numeric(x), y = as.numeric(y)) %>% 
  as.tibble()
1 голос
/ 13 февраля 2020

Мы можем создать для этого функцию

tibble(x, y) %>%
       crossing(n)

данные

n <- 1:3
1 голос
/ 13 февраля 2020

Ниже приведено решение с использованием purrr::map_df:

library(tidyverse)

map_df(n, ~tibble(n=.x, x, y))

      n     x     y
  <dbl> <dbl> <dbl>
1     1     4     7
2     1     5     8
3     1     6     9
4     2     4     7
5     2     5     8
6     2     6     9

Если вам нужны значения, отсортированные точно так же, как в примере с выходом, добавьте %>% arrange(x, y) к выводу map.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...