R:识别列对并计算差异

时间:2017-05-29 15:38:14

标签: r

我有这样的数据框(df)(在下面找到dput):

X   A_T  B_N  B_T C_N   C_T  C_T.1  C_T.2  D_N  D_T  D_T.1  E_T  F_N
w   1    5    9   13    17   21     25     29   33   37     41   45
x   2    6   10   14    18   22     26     30   34   38     42   46
y   3    7   11   15    19   23     27     31   35   39     43   47
z   4    8   12   16    20   24     28     32   36   40     44   48

是列(在第一个之后)有一个前缀(这里是A到F,但可以是包含字符,数字或符号的任何其他字符串),然后是“_”,然后是“T”或“N” 。然后以_T结尾的ID也可以在末尾具有“.1”或“.2”。

我想要做的是首先在这样的表中识别相同前缀的所有可能的ID对(其中m1和m2仅表示每对的member1和member2,m1是“_N”成员, m2是“_T”成员,“pair”是该对的名称):

m1    m2     pair
B_N   B_T    B
C_N   C_T    C
C_N   C_T.1  C.1
C_N   C_T.2  C.2
D_N   D_T    D
D_N   D_T.1  D.1

请注意,不属于一对的ID将被丢弃(如A,E和F)。

然后我想计算每对的m2和m1的列(来自df)之间的差异,并将它放在一个新表中,其中每列是一对,如下所示:

X   B   C   C.1   C.2   D   D.1
w   4   4   8     12    4   8
x   4   4   8     12    4   8
y   4   4   8     12    4   8
z   4   4   8     12    4   8

请注意,该解决方案需要适用于我们无法单独指示值的较大数据帧,以及ID前缀可能是包含字符,数字或符号的任何字符串的数据帧。

如果有什么我可以澄清的话,请告诉我,谢谢你的帮助!

df的输入:

> dput(df)
structure(c("w", "x", "y", "z", "1", "2", "3", "4", "5", "6", 
"7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", 
"18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", 
"29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", 
"40", "41", "42", "43", "44", "45", "46", "47", "48"), .Dim = c(4L, 
13L), .Dimnames = list(NULL, c("X", "A_T", "B_N", "B_T", "C_N", 
"C_T", "C_T.1", "C_T.2", "D_N", "D_T", "D_T.1", "E_T", "F_N")), class = "noquote")

1 个答案:

答案 0 :(得分:1)

以下是使用tidyverse工具执行此操作的方法。

tidyr用于重塑数据 - 首先是长,然后是宽。

dplyr用于一般数据操作,包括inner_join

stringr仅用于创建pair变量的字符串操作。

library(dplyr)
library(tidyr)
library(stringr)

创建数据

df_orig <- readr::read_table2(
"X   A_T  B_N  B_T C_N   C_T  C_T.1  C_T.2  D_N  D_T  D_T.1  E_T  F_N
w   1    5    9   13    17   21     25     29   33   37     41   45
x   2    6   10   14    18   22     26     30   34   38     42   46
y   3    7   11   15    19   23     27     31   35   39     43   47
z   4    8   12   16    20   24     28     32   36   40     44   48")

将数据重塑为长

df_long <- df_orig %>% 
  gather("key", "value", -X) %>% 
  separate(key, c("prefix", "suffix"), sep = "_")

df_long

#> # A tibble: 48 x 4
#>        X prefix suffix value
#>  * <chr>  <chr>  <chr> <int>
#>  1     w      A      T     1
#>  2     x      A      T     2
#>  3     y      A      T     3
#>  4     z      A      T     4
#>  5     w      B      N     5
#>  6     x      B      N     6
#>  7     y      B      N     7
#>  8     z      B      N     8
#>  9     w      B      T     9
#> 10     x      B      T    10
#> # ... with 38 more rows

NT

创建单独的表格
df_n <- df_long %>% 
  filter(suffix == "N")

df_t <- df_long %>% 
  filter(suffix != "N")

合并NT表以获取对,计算差异,重新整形

在这里,您应该使用inner_join删除仅出现在其中一个案例中的案例,例如AEF

df_merged <- inner_join(df_n, df_t, by = c("X", "prefix"), suffix = c("_m1", "_m2")) %>% 
  mutate(pair = str_c(prefix, str_sub(suffix_m2, 2)),
         value = value_m2 - value_m1) %>% 
  select(X, pair, value) %>% 
  spread(pair, value)

df_merged

#> # A tibble: 4 x 7
#>       X     B     C   C.1   C.2     D   D.1
#> * <chr> <int> <int> <int> <int> <int> <int>
#> 1     w     4     4     8    12     4     8
#> 2     x     4     4     8    12     4     8
#> 3     y     4     4     8    12     4     8
#> 4     z     4     4     8    12     4     8