R: Разреженный?Преобразование данных для матрицы совмещения - PullRequest
0 голосов
/ 25 мая 2018

Я био мажор, использующий R для генерации некоторых визуализаций, показывающих, какие человеческие белки (унипроты) нацелены на различные бактериальные штаммы.

# sample data
human.uniprots <- c("P15311", "P0CG48", "Q8WYH8", "P42224", "Q9NXR8",
                    "P40763", "P05067", "P60709", "Q9UDW1", "Q9H160",
                    "Q9UKL0", "P26038", "P61244", "O95817", "Q09472",
                    "P15311","P05067", "P60709", "Q9UDW1", "Q9H160")
strains <- rep(c("A", "B", "C", "C"), each = 5)
final <- cbind(human.uniprots, strains)

Я пытаюсь сгенерировать матрицу совместного появления /тепловая карта ... что-то вроде

h.map <- data.frame(matrix(nrow = length(unique(human.uniprots)),
ncol = length(unique(strains)) + 1))
h.map.cols <- c("human_uniprots", "A", "B", "C")
colnames(h.map) <- h.map.cols

... где столбцы имеют штаммы, строки содержат белки, а ячейки фрейма данных заполняются количеством раз, когда белок взаимодействует сштамм.Таким образом, если штаммы A, B и C взаимодействуют с унипротом, все они должны иметь значение 3 в своих клетках для этого ряда унипрот.

Я попытался составить список кортежей с уникальным штаммом и human_uniprots, затем найти тот кортеж, который соответствует паре штамм и человек-унипрот из матрицы, которую я хочу заполнить, и добавить «1», если естьсовпадение ... но я не уверен, как работать с кортежами в R. Тогда я увидел это: Заполнение матрицы совпадений

Что я хочу, но яя не понимаю, использование или синтаксис ... это sparse () даже функция в R?

Дополнительно ... было бы неплохо ранжировать все белки по тем, которые взаимодействуют со всеми штаммами.Таким образом, все белки, которые взаимодействуют со всеми штаммами, должны быть наверху, затем следуют те, которые взаимодействуют с 2 штаммами, а затем с 1 штаммом ...

Ответы [ 3 ]

0 голосов
/ 26 мая 2018

Вы можете сделать это, используя table, или, если вы хотите, чтобы оно было разреженным, вы можете использовать xtabs.

Так что для вашего примера вы можете использовать либо

tab <- table(final[,"human.uniprots"], final[,"strains"]) 
tab* rowSums(tab)

, либоsparse

tab <- xtabs(~human.uniprots + strains, final, sparse=TRUE)
tab <- tab*Matrix::rowSums(tab)

Затем вы можете построить его, используя

Matrix::image(tab, scales=list(y=list(at=1:nrow(tab), label=rownames(tab)),
                               x=list(at=1:ncol(tab), label=colnames(tab))),
              ylab="uniprots",
              xlab="strains")

enter image description here

Вы также можете ранжировать строки по вхождению

r <- order(-Matrix::rowSums(tab))

# and then reorder the rows of the matrix and the labels
Matrix::image(tab[r,],
              scales=list(y=list(at=1:nrow(tab), label=rownames(tab)),
                          x=list(at=1:ncol(tab), label=colnames(tab)[r])),
                  ylab="uniprots",
                  xlab="strains")
0 голосов
/ 26 мая 2018

sparse() - это, по-видимому, функция MATLAB.Вы описываете двудольную сеть, представленную матрицей инцидентности.

human.uniprots <- c("P15311", "P0CG48", "Q8WYH8", "P42224", "Q9NXR8",
                    "P40763", "P05067", "P60709", "Q9UDW1", "Q9H160",
                    "Q9UKL0", "P26038", "P61244", "O95817", "Q09472",
                    "P15311","P05067", "P60709", "Q9UDW1", "Q9H160")
strains <- rep(c("A", "B", "C", "D"), each = 5)
final <- cbind(human.uniprots, strains)

final_df <- as.data.frame(final)

library(igraph) # install.packages("igraph")
g <- graph_from_data_frame(final_df, directed = FALSE)
V(g)$type <- ifelse(V(g)$name %in% strains, FALSE, TRUE)

as_incidence_matrix(g)
#>   P15311 P0CG48 Q8WYH8 P42224 Q9NXR8 P40763 P05067 P60709 Q9UDW1 Q9H160
#> A      1      1      1      1      1      0      0      0      0      0
#> B      0      0      0      0      0      1      1      1      1      1
#> C      0      0      0      0      0      0      0      0      0      0
#> D      1      0      0      0      0      0      1      1      1      1
#>   Q9UKL0 P26038 P61244 O95817 Q09472
#> A      0      0      0      0      0
#> B      0      0      0      0      0
#> C      1      1      1      1      1
#> D      0      0      0      0      0

или .....

V(g)$type <- ifelse(V(g)$name %in% strains, TRUE, FALSE)
                                        # swap TRUE/FALSE

as_incidence_matrix(g)
#>        A B C D
#> P15311 1 0 0 1
#> P0CG48 1 0 0 0
#> Q8WYH8 1 0 0 0
#> P42224 1 0 0 0
#> Q9NXR8 1 0 0 0
#> P40763 0 1 0 0
#> P05067 0 1 0 1
#> P60709 0 1 0 1
#> Q9UDW1 0 1 0 1
#> Q9H160 0 1 0 1
#> Q9UKL0 0 0 1 0
#> P26038 0 0 1 0
#> P61244 0 0 1 0
#> O95817 0 0 1 0
#> Q09472 0 0 1 0

Создано в 2018-05-25 с помощью представпакет (v0.2.0).

0 голосов
/ 25 мая 2018

Используя dplyr, вы можете group_by, count и spread, чтобы получить счет за деформацию.Затем замените счет на деформацию общим счетом для этой строки, используя rowSums():

library(dplyr)

as.data.frame(final) %>%
  group_by(human.uniprots, strains) %>%
  count() %>%
  spread(strains, n) %>%
  ungroup() %>%
  mutate(total_n = rowSums(.[2:ncol(.)])) %>%
  mutate_if(is.numeric, funs(ifelse(. == 0, 0, total_n))) %>%
  select(-total_n)

  # A tibble: 15 x 5
   human.uniprots     A     B     C     D
   <fct>          <dbl> <dbl> <dbl> <dbl>
 1 O95817            0.    0.    1.    0.
 2 P05067            0.    2.    0.    2.
 3 P0CG48            1.    0.    0.    0.
 4 P15311            2.    0.    0.    2.
 5 P26038            0.    0.    1.    0.
 6 P40763            0.    1.    0.    0.
 7 P42224            1.    0.    0.    0.
 8 P60709            0.    2.    0.    2.
 9 P61244            0.    0.    1.    0.
10 Q09472            0.    0.    1.    0.
11 Q8WYH8            1.    0.    0.    0.
12 Q9H160            0.    2.    0.    2.
13 Q9NXR8            1.    0.    0.    0.
14 Q9UDW1            0.    2.    0.    2.
15 Q9UKL0            0.    0.    1.    0.
...