R 如何在来自两个数据帧的分组值之间执行操作

R 如何在来自两个数据帧的分组值之间执行操作,r,dplyr,tidyverse,broom,R,Dplyr,Tidyverse,Broom,我有两个数据帧: src\u tbl样本名称crt sr条件分数 #>1 S1 0.079 0.592 x1 0.077 #>2 S2 0.082 0.549 x1 0.075 #>3 S1 0.079 0.592 x2 0.483 #>4 S2 0.082 0.549 x2 0.268 #>5 S1 0.079 0.592 x3 0.555 #>6 S2 0.082 0.549 x3 0.120 参考样本名称crt sr条件分数 #>1 P1 12 r1 0.200 #>2 P2 1 2

我有两个数据帧:


src\u tbl样本名称crt sr条件分数
#>1 S1 0.079 0.592 x1 0.077
#>2 S2 0.082 0.549 x1 0.075
#>3 S1 0.079 0.592 x2 0.483
#>4 S2 0.082 0.549 x2 0.268
#>5 S1 0.079 0.592 x3 0.555
#>6 S2 0.082 0.549 x3 0.120
参考样本名称crt sr条件分数
#>1 P1 12 r1 0.200
#>2 P2 1 2 r1 0.201
#>3 P3 1 2 r1 0.199
#>4 P1 1 2 r2 0.200
#>5 P2 1 2 r2 0.202
#>6 P3 12 r2 0.200
#>7 P1 1 2 r3 0.200
#>8 P2 1 2 r3 0.204
#>9 P3 1 2 r3 0.197
我想做的是对两个数据帧中按
Sample\u name
分组的
score
列执行操作(
ks.test()
)。例如,S1和P1的KS试验的p值为:


#在src\u tbl中
s1 1 0.66667 0.5175508双面Kolmogorov-Smirnov试验
我想做的是对所有操作执行所有操作,以便最终得到如下表

src ref p.value
S1 P1 0.5175508
S1 P2 0.6
S1 P3 0.6
S2 P1 0.5175508
S2 P2 0.6
S2 P3 0.6

我该怎么做?最好是快速,因为
ref_table
中的样本数量可能很大(P1、P2……P10k)。

虽然花了一些时间,但我拼凑了一个简单的解决方案。我相信有一种更优雅的方式来处理像
ddply
这样的东西,但我无法理解。(注意,我缩短了其中一个数据帧,因此我的p值与您的略有不同)

库(dplyr)
图书馆(tidyr)

ref_tbl这里是
tidyverse
中的解决方案。我首先将分数嵌套在每个源数据集中:

ref_tbl <- ref_tbl %>% 
  mutate(ref = as.factor(Sample_name),
         score_ref = as.numeric(score)) %>%
  select(ref, score_ref) %>%
  tidyr::nest(score_ref)

ref_tbl
# A tibble: 3 x 2
     ref                    data
  <fctr>                  <list>
1     P1 <tibble [3 x 1]>
2     P2 <tibble [3 x 1]>
3     P3 <tibble [3 x 1]>

src_tbl <- src_tbl %>% 
  mutate(src = as.factor(Sample_name),
         score_src = as.numeric(score))  %>% 
  select(src, score_src) %>% 
  tidyr::nest(score_src)

src_tbl  
# A tibble: 2 x 2
     src                    data
  <fctr>                  <list>
1     S1 <tibble [3 x 1]>
2     S2 <tibble [3 x 1]>

两个数据帧是否总是长度不同?@J.con
src_tbl
ref_tbl
可以是相同或不同的维度。谢谢,您的解决方案对我很重要。但是你的方法中可能有一个缺陷。请看这一点,我认为这种方法是好的,但是您必须注意ks.test中参数的顺序。对于大数据集,可能采用
data.table
方法更快。
ref_tbl <- ref_tbl %>% 
  mutate(ref = as.factor(Sample_name),
         score_ref = as.numeric(score)) %>%
  select(ref, score_ref) %>%
  tidyr::nest(score_ref)

ref_tbl
# A tibble: 3 x 2
     ref                    data
  <fctr>                  <list>
1     P1 <tibble [3 x 1]>
2     P2 <tibble [3 x 1]>
3     P3 <tibble [3 x 1]>

src_tbl <- src_tbl %>% 
  mutate(src = as.factor(Sample_name),
         score_src = as.numeric(score))  %>% 
  select(src, score_src) %>% 
  tidyr::nest(score_src)

src_tbl  
# A tibble: 2 x 2
     src                    data
  <fctr>                  <list>
1     S1 <tibble [3 x 1]>
2     S2 <tibble [3 x 1]>
all_comb <- as_data_frame(expand.grid(src = src_tbl$src, ref = ref_tbl$ref))

all_comb
# A tibble: 6 x 2
     src    ref
  <fctr> <fctr>
1     S1     P1
2     S2     P1
3     S1     P2
4     S2     P2
5     S1     P3
6     S2     P3
all_comb <- all_comb %>% 
  left_join(ref_tbl, by = "ref") %>% 
  left_join(src_tbl, by = "src") %>%
  mutate(data = purrr::map2(data.x, data.y, bind_cols)) %>%
  select(-data.x, -data.y)

all_comb 
# A tibble: 6 x 3
     src    ref                    data
  <fctr> <fctr>                  <list>
1     S1     P1 <tibble [3 x 2]>
2     S2     P1 <tibble [3 x 2]>
3     S1     P2 <tibble [3 x 2]>
4     S2     P2 <tibble [3 x 2]>
5     S1     P3 <tibble [3 x 2]>
6     S2     P3 <tibble [3 x 2]>
final <- all_comb %>%
  mutate(ks = purrr::map(data,  ~ks.test(.$score_ref, .$score_src)),
  tidied = purrr::map(ks, broom::tidy)) %>%
  tidyr::unnest(tidied) %>%
  select(src, ref, p.value)
Warning message: cannot compute exact p-value with ties
Warning message: cannot compute exact p-value with ties

final
# A tibble: 6 x 3
     src    ref   p.value
  <fctr> <fctr>     <dbl>
1     S1     P1 0.5175508
2     S2     P1 0.5175508
3     S1     P2 0.6000000
4     S2     P2 0.6000000
5     S1     P3 0.6000000
6     S2     P3 0.6000000