在保留样本配对的同时置换矩阵的标签

Permute labels of matrix while preserving the pairing of the samples

我有一个矩阵,它有 490 行(特征;F1..F490)和 350 列(350 个样本;s1..s350)。 第一列如下所示:

Drug    T   T   T   C   T
Sample  s1  s2  s3  s4  s5 .....
Pair    16  81 -16  32 -81 .....
Cond    B   D    B   B  D  .....
F1      34  23   12     9  .....
F2      78       11  87 10 .....
...

(有缺失数据,属于正常现象)

有2个条件; B 和 D。有 2 种药物(T 和 C)。 样本是配对的。因此,例如,s1 和 s3 是配对的,因为它们的 Pair 值相同(绝对值)。

我想做的是将药物标签置换 1000 次,同时保留配对信息(配对值)。因此,一对应该始终具有相同的条件(在本例中为 B)和相同的对值(在本例中为 16 和 -16)。此外,它们必须具有相同的药物标签。例子; s1 和 s3 是一对;它们具有相同的 Pair 值,都是 B 并且都具有药物标签 T.

因此 1000 个置换文件中的 1 个应该看起来像这样,例如:

Drug    C   T   C   T   T
Sample  s1  s2  s3  s4  s5 .....
Pair    16  81 -16  32 -81 .....
Cond    B   D    B   B  D  .....
F1      34  23   12     9  .....
F2      78       11  87 10 .....
...

样品不整齐我不介意

我已经尝试过置换和采样(在 R 中),但我似乎无法在包含上述条件的同时找到一种方法来做到这一点。如果这很明显,我很抱歉。

我想将这些置换文件 (n=1000) 用于我已经编码的下游分析。

非常感谢您的意见。

确定对的列索引,找到与对关联的药物,将药物打乱,然后将打乱的药物分配回对。

use List::Util qw( shuffle );

my @matrix = (
   [ 'Drug',    'T',   'T',  'T',   'C',  'T',   ..... ],
   [ 'Sample',  's1',  's2', 's3',  's4', 's5',  ..... ],
   [ 'Pair',    '16',  '81', '-16', '32', '-81', ..... ],
   [ 'Cond',    'B',   'D',  'B',   'B',  'D',   ..... ],
   [ 'F1',      '34',  '23', '12',  '',   '9',   ..... ],
   [ 'F2',      '78',  '',   '11',  '87', '10',  ..... ],
);

my %pair_col_idxs_by_key;
{
   my $drug_row = $matrix[0];
   for my $col_idx (1..$#$drug_row) {
   my $row = $matrix[$col_idx];
   push @{ $pair_col_idxs_by_key{join(":", abs($row->[2]), $row->[3])} }, $pair_col_idxs;
}

my @all_pair_col_idxs = values(%pair_col_idxs_by_key);
my @drugs = map { $matrix[ 0 ][ $_->[0] ] } @all_pair_col_idxs;

@drugs = shuffle @drugs;

# Keep reshuffling until you get a previously unseen result.

for my $i (0..$#all_pair_col_idxs) {
   my $pair_col_idxs = $all_pair_col_idxs[$i];
   my $drug          = $drug[$i];

   $matrix[0][$_] = $drug for @$pair_col_idxs;
}

给定数据 dfPair的绝对值分组,然后采样/置换Drug分组对。最后 返回 Pairs 的绝对值。使用 dplyr:

t_df <- as.data.frame(t(df))                    # transposed to use features as cols
t_df$Pair <- as.numeric(as.character(t_df$Pair)

library(dplyr)

# Wrap this into a function to call/ permute 1000 times
df_out <- t_df %>% mutate(abs_pair = abs(Pair)) %>% 
              group_by(abs_pair) %>% filter(row_number()==1) %>% 
          ungroup() %>% mutate(Permuted_drug = sample(Drug, n())) %>%      
              select(abs_pair, Permuted_drug) %>%
          inner_join(t_df %>% mutate(abs_pair = abs(Pair)))

df_out
#  abs_pair Permuted_drug Drug  Sample  Pair Cond 
#     <dbl> <fct>         <fct> <fct>  <dbl> <fct>
#1       16 T             T     s1        16 B    
#2       16 T             T     s3       -16 B    
#3       81 C             T     s2        81 D    
#4       81 C             T     s5       -81 D    
#5       32 T             C     s4        32 B    

使用的数据:

df <- read.table(text = "Drug    T   T   T   C   T
Sample  s1  s2  s3  s4  s5
Pair    16  81 -16  32 -81
Cond    B   D    B   B  D", row.names = 1)