2017-10-24 3 views
2

Ich möchte ein tibble umformen, ohne expand.grid zu verwenden. Während expand.grid + delete obs + delete löschen "flipped duplicates" (d. H. A, b ist das gleiche wie b, a) soll funktionieren, wäre es ziemlich langsam zu berechnen, vorausgesetzt, die vielen Kombinationen, die ich habe.tidyr reshape tibble ohne expand.grid

Dies ist eine Dummy-Version von dem, was ich erreichen möchte:

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 

Dies funktioniert jedoch extrem ineffizient:

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 

Vielen Dank im Voraus !!

+0

Können Sie Ihr Problem näher erläutern? Ich kann nicht verstehen, welches endgültige Format du bekommen willst. – PoGibas

Antwort

1

Wie wäre es mit einem inner join und dann Filter für einzigartige Kombinationen?

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 
+0

Ich werde versuchen, die Machbarkeit so schnell wie möglich zu überprüfen :) – pachamaltese

1

Ist diese Basis für Sie R Lösung arbeiten ?:

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

ich combn einen Versuch geben würde, mit purrr::map

Ihre Daten kombiniert

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

Lösung

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) 

Ausgabe

# 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