Применить операцию ко всем парам строк - PullRequest
1 голос
/ 05 февраля 2020

У меня есть тиббл в этом формате:

   position condition replicate  value
   <dbl>    <chr>     <chr>      <dbl>
 1 10       1         a          0.16
 2 10       1         b          0.21
 3 10       2         a          0.19
 4 10       2         b          0.38
 5 10       3         a          0.12
 6 10       3         b          0.35
 7 20       1         a          0.22
 8 20       1         b          0.24
 9 20       2         a          0.56
10 20       2         b          0.47
11 20       3         a          0.14
12 20       3         b          0.23
 ...

Из этого я хочу получить различия между всеми парами повторений для пары условий на позицию:

   position  1.a-2.a  1.a-2.b  1.b-2.a  1.b-2.b  1.a-3.a  1.a-3.b  1.b-3.a  1.b-3.b ...
   <dbl>     <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
 1 10        0.13     0.21     0.13     0.16     ...      ...      ...      ...
 2 20        ...      ...      ...      ...      ...      ...      ...      ...
 3 30        ...      ...      ...      ...      ...      ...      ...      ...
 ...

И затем суммируйте, чтобы получить медиану для пары условий на позицию:

   position  median(abs(1.a-2.a), abs(1.a-2.b), abs(1.b-2.a), abs(1.b-2.b)) ...
   <dbl>     <dbl>
 1 10        0.0161
 2 20        ...
 3 30        ...
 ...

Я пытался table %>% spread(replicate, value) разбить повторяющиеся значения на столбцы, но я не знаю, откуда go оттуда , Мне нужно сделать решение обобщаемым, так как я не знаю, сколько у меня будет условий или повторов. Как я могу достичь этого?

РЕДАКТИРОВАТЬ:

Примерно так:

table %>%
  unite(condition.replicate, c(condition, replicate), sep = ".") %>%
  spread(condition.replicate, value) %>% group_by(position) %>%
  uncount(2)

Дает мне это:

    position  `1.a`   `1.b`  `2.a`  `2.b`  ...
    <dbl>     <dbl>   <dbl>  <dbl>  <dbl>
1   10        0.16    0.14   0.61   0.86
2   10        0.16    0.14   0.61   0.86

Может быть, есть способ повторить столбцы так, чтобы они перекрывались так:

    position  `1.a`   `1.b`  `2.a`  `2.b`  `1.a`   `1.b`  `2.a`  `2.b` ...
    <dbl>     <dbl>   <dbl>  <dbl>  <dbl>  <dbl>   <dbl>  <dbl>  <dbl>
1   10        0.16    0.14   0.61   0.86   0.16    0.14   0.61   0.86
2   10        0.16    0.16   0.16   0.16   0.14    0.14   0.14   0.14
    position  `1.a`   `1.a`  `1.a`  `1.a`  `1.b`   `1.b`  `1.b`  `1.b` ...

Тогда я мог бы просто summarize и получить разницу между строками.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2020

Если вы используете tidyverse, вы можете попробовать этот подход. Это не так здорово, но может дать вам то, что вы хотите.

library(tidyverse)

wide_df <- df %>%
  unite(con_rep, c(condition, replicate), sep = ".") %>%
  pivot_wider(id_cols = position, names_from = con_rep, values_from = value) %>%
  as.data.frame(.)

data.frame(position = wide_df$position, combn(wide_df[-1], 2, function(x) x[,1]-x[,2])) %>%
  setNames(c("position", apply(combn(names(wide_df[-1]), 2), 2, paste0, collapse = "-")))

Вывод

  position 1.a-1.b 1.a-2.a 1.a-2.b 1.a-3.a 1.a-3.b 1.b-2.a 1.b-2.b 1.b-3.a 1.b-3.b 2.a-2.b 2.a-3.a 2.a-3.b 2.b-3.a
1       10   -0.05   -0.03   -0.22    0.04   -0.19    0.02   -0.17    0.09   -0.14   -0.19    0.07   -0.16    0.26
2       20   -0.02   -0.34   -0.25    0.08   -0.01   -0.32   -0.23    0.10    0.01    0.09    0.42    0.33    0.33
  2.b-3.b 3.a-3.b
1    0.03   -0.23
2    0.24   -0.09
0 голосов
/ 05 февраля 2020

Вы можете сделать матрицу различий довольно легко с помощью вложенного lapply:

# Make result matrix
result <- do.call(rbind, 
                  lapply(split(df, df$position), function(x)
                    do.call(c, lapply(x$value, 
                                      function(y) y - x$value))))

Имена немного сложнее

# Names for result matrix
df$unique_mix <- paste0(df$condition, ".", df$replicate)
combos <- expand.grid(unique(df$unique_mix), unique(df$unique_mix)) 
colnames(result) <- paste(combos[,1], "-", combos[,2])

Но это должно дать вам то, что вы можете работа с:

#>    1.a - 1.a 1.b - 1.a 2.a - 1.a 2.b - 1.a 3.a - 1.a 3.b - 1.a 1.a - 1.b 1.b - 1.b
#> 10         0     -0.05     -0.03     -0.22      0.04     -0.19      0.05         0
#> 20         0     -0.02     -0.34     -0.25      0.08     -0.01      0.02         0
#>    2.a - 1.b 2.b - 1.b 3.a - 1.b 3.b - 1.b 1.a - 2.a 1.b - 2.a 2.a - 2.a 2.b - 2.a
#> 10      0.02     -0.17      0.09     -0.14      0.03     -0.02         0     -0.19
#> 20     -0.32     -0.23      0.10      0.01      0.34      0.32         0      0.09
#>    3.a - 2.a 3.b - 2.a 1.a - 2.b 1.b - 2.b 2.a - 2.b 2.b - 2.b 3.a - 2.b 3.b - 2.b
#> 10      0.07     -0.16      0.22      0.17      0.19         0      0.26      0.03
#> 20      0.42      0.33      0.25      0.23     -0.09         0      0.33      0.24
#>    1.a - 3.a 1.b - 3.a 2.a - 3.a 2.b - 3.a 3.a - 3.a 3.b - 3.a 1.a - 3.b 1.b - 3.b
#> 10     -0.04     -0.09     -0.07     -0.26         0     -0.23      0.19      0.14
#> 20     -0.08     -0.10     -0.42     -0.33         0     -0.09      0.01     -0.01
#>    2.a - 3.b 2.b - 3.b 3.a - 3.b 3.b - 3.b
#> 10      0.16     -0.03      0.23         0
#> 20     -0.33     -0.24      0.09         0
...