Czy istnieje jakiś inner_join równoważny dla tablic 3D i może być osiągnięta łączenie struktury 2D do struktury 3D?

Zobaczmy, czy to ma sens:

Mam tablicę liczb całkowitych 3D (dane zliczania mikrobiomów).

  • Wymiar 1: replikuje 1: 100
  • Wymiar 2: próbki
  • Wymiar 3: Taksony

Mam stół 2D metadanych.

  • Wymiar 1: próbki
  • Wymiar 2: typ metadanych (rozcieńczenie, data próbki itp.)

Istnieje jedna kolumna w tabeli metadanych 2D (nazwy próbek), które pasują do etykiet drugiego wymiaru w tablicy.

Czy mogę w jakiś sposób dołączyć do tych dwóch, takich, że zachowuję strukturę tablicy i dodam metadane dla każdej próbki?

Czy muszę po prostu stopić / stosować tablicę na super długi stół 2D?

Dzięki za pomoc!

-edytować

Powiedzmy, że generuję tabelę A i "Tabela" B "z następującym kodem:

a <- array(1:10,c(2,4,3))
b <- data.frame("thing" = c("stuff", "foo", "dodad"), "data" = c(10,20,30), "match" = c("first","second","third"))
dimnames(a) <- list(c("A", "B"), c("one", "two", "three", "four"), c("first", "second", "third"))

Jak widać, mam kolumnę "Mecz" w tabeli "B", że chciałbym dołączyć do nazwisk wymiarowych [[[3]].

Więc jeśli spojrzymy na "A" i "B"

> a
, , first

  one two three four
A   1   3     5    7
B   2   4     6    8

, , second

  one two three four
A   9   1     3    5
B  10   2     4    6

, , third

  one two three four
A   7   9     1    3
B   8  10     2    4

> b
  thing data  match
1 stuff   10  first
2   foo   20 second
3 dodad   30  third

Chciałbym, na przykład tablica

, , third

      one two three four
    A   7   9     1    3
    B   8  10     2    4

Aby uzyskać elementy "Dodad" i "30" związane z nią z etykietami "rzecz" i "DATA".

W przypadku realnego zestawu danych, chcę mieć "nazwę pacjenta" zamiast "rzeczy" i "rozcieńczania" zamiast "danych" i używać tych elementów jako środka, aby wyciągnąć plasterki z tablicy, aby uruchomić analizy statystyczne.

0
GnomGnom 1 kwiecień 2020, 17:35

1 odpowiedź

Najlepsza odpowiedź

Nie pokazujesz, co zamyślasz, więc zgaduję.

Jeśli zaczniesz od a (z dims axbxc) i b (Dims DXE), a następnie należy dostać tablicę z przyciemniaczami AXBXD.

a[,,b[,"match"]]
# , , first
#   one two three four
# A   1   3     5    7
# B   2   4     6    8
# , , second
#   one two three four
# A   9   1     3    5
# B  10   2     4    6
# , , third
#   one two three four
# A   7   9     1    3
# B   8  10     2    4

Jeśli chodzi o połączone wyjście, z dostarczonymi danymi, których podałeś, nie może się zdarzyć: Matrix {X0}} ma ograniczenie, że wszystkie dane muszą być tą samą klasą, ale twój {X1}} jest ramą o różnych klasach . Więc jeśli potrzebujesz utrzymać numery w a i ciągów lub czynniki w b, nie można po prostu połączyć jednego do drugiego.

Masz kilka opcji:

  1. Jeśli twoja druga ramka naprawdę może być matrycą, możemy to zrobić.

    ### a naive conversion, your case may vary with real data
    bnum <- sapply(b, as.integer)
    dim(bnum) <- c(dim(bnum), 1)
    dimnames(bnum) <- list(rownames(b), colnames(b), NULL)
    bnum
    # , , 1
    #   thing data match
    # 1     3   10     1
    # 2     2   20     2
    # 3     1   30     3
    
    ### the solution
    abind::abind(
      apply(bnum[,-3,1], 2:1, rep, times = dim(a)[1]),
      a[,,bnum[,"match",1]],
      along = 2
    )
    # , , first
    #   thing data one two three four
    # A     3   10   1   3     5    7
    # B     3   10   2   4     6    8
    # , , second
    #   thing data one two three four
    # A     2   20   9   1     3    5
    # B     2   20  10   2     4    6
    # , , third
    #   thing data one two three four
    # A     1   30   7   9     1    3
    # B     1   30   8  10     2    4
    
  2. Jeśli musisz zachować b as-is, nie można wykonać tablicy 3-D. Opcja jest gniazdo każdej warstwy a w modzie kolumnowej.

    out <- within(b, { mtx = lapply(match, function(m) a[,,m]) })
    out
    #   thing data  match                     mtx
    # 1 stuff   10  first  1, 2, 3, 4, 5, 6, 7, 8
    # 2   foo   20 second 9, 10, 1, 2, 3, 4, 5, 6
    # 3 dodad   30  third 7, 8, 9, 10, 1, 2, 3, 4
    

    Chociaż wygląda tak, jakby stracił układ warstwy Z {X0}}, to tylko słabą reprezentację konsoli. Jest nadal dobry:

    out$mtx[[1]]
    #   one two three four
    # A   1   3     5    7
    # B   2   4     6    8
    

    Można to również zrobić za pomocą dplyr i data.table, jeśli jesteś zainteresowany.

    library(dplyr)
    out <- b %>%
      mutate(mtx = lapply(match, function(m) a[,,m]))
    # option to use purrr::map instead of lapply
    
    library(data.table)
    out <- as.data.table(b)[, mtx := lapply(match, function(m) a[,,m]) ]
    
0
r2evans 1 kwiecień 2020, 16:02