Я хотел бы изменить тиббл без использования expand.grid. В то время как expand.grid + удаляет отсутствующие obs + удаляет «перевернутые дубликаты» (т. Е. A, b - то же самое, что b, a), будет работать, вычисление будет довольно медленным, если у меня будет много комбинаций.

Это фиктивная версия того, чего я хочу достичь:

library(dplyr)
library(tidyr)

initial_data <- tibble(x = c("east","east","east"), y = c("a","b","c"), z = c(0.1,0.2,0.3))

> initial_data
# A tibble: 3 x 3
      x     y     z
  <chr> <chr> <dbl>
1  east     a   0.1
2  east     b   0.2
3  east     c   0.3

final_data <- tibble(x = c("east","east","east"), y1 = c("a","a","b"), y2 = c("b","c","c"), z1 = c(0.1,0.1,0.2), z2 = c(0.2,0.3,0.3))

> final_data
# A tibble: 3 x 5
      x    y1    y2    z1    z2
  <chr> <chr> <chr> <dbl> <dbl>
1  east     a     b   0.1   0.2
2  east     a     c   0.1   0.3
3  east     b     c   0.2   0.3

Это работает, но крайне неэффективно:

expand_data <- as_tibble(expand.grid(initial_data$x, initial_data$y, initial_data$y)) %>% 
  filter(Var2 != Var3) %>% 
  distinct()

index <- !duplicated(t(apply(expand_data, 1, sort)))
expand_data <- expand_data[index, ] %>% 
  left_join(initial_data, by = c("Var1" = "x", "Var2" = "y")) %>% 
  left_join(initial_data, by = c("Var1" = "x", "Var3" = "y"))

> expand_data
# A tibble: 3 x 5
   Var1  Var2  Var3   z.x   z.y
  <chr> <chr> <chr> <dbl> <dbl>
1  east     b     a   0.2   0.1
2  east     c     a   0.3   0.1
3  east     c     b   0.3   0.2

Спасибо заранее !!

2
pachamaltese 24 Окт 2017 в 16:48

3 ответа

Лучший ответ

Как насчет inner join, а затем фильтра для уникальных комбинаций?

library(dplyr)
inner_join(initial_data, initial_data,
           suffix = c('1', '2'), by = 'x') %>%
    filter(y1 < y2) %>%
    select(x, y1, y2, z1, z2)

#      x y1 y2  z1  z2
# 1 east  a  b 0.1 0.2
# 2 east  a  c 0.1 0.3
# 3 east  b  c 0.2 0.3
1
mt1022 24 Окт 2017 в 14:18

Я бы дал combn попытку в сочетании с purrr::map

Ваши данные

initial_data <- tibble(x = c("east","east","east"), y = c("a","b","c"), z = c(0.1,0.2,0.3))

Решение

initial_data %>%
  nest(-x) %>%
  mutate(data = map(data, ~cbind(as_tibble(t(combn(.x$y, 2))) %>% setNames(paste0("y", 1:2)), 
                        as_tibble(t(combn(initial_data$z, 2))) %>% setNames(paste0("z", 1:2))) )) %>%
  unnest(data)

Выход

# A tibble: 3 x 5
      # x    y1    y2    z1    z2
  # <chr> <chr> <chr> <dbl> <dbl>
# 1  east     a     b   0.1   0.2
# 2  east     a     c   0.1   0.3
# 3  east     b     c   0.2   0.3
1
CPak 24 Окт 2017 в 14:24

Это базовое решение R работает на вас ?:

data.frame(x = rep("east", 3),
           matrix(rep(initial_data$y, each = 2), 3), 
           matrix(rep(initial_data$z, each = 2), 3))

#      x X1 X2 X1.1 X2.1
# 1 east  a  b  0.1  0.2
# 2 east  a  c  0.1  0.3
# 3 east  b  c  0.2  0.3
1
PoGibas 24 Окт 2017 в 14:19