1 折线图

Code
f4h <-read_excel("data/01source.xlsx", sheet = "Fig.4", range = "A20:P23")
#> New names:
#> • `` -> `...3`
#> • `` -> `...4`
#> • `` -> `...5`
#> • `` -> `...6`
#> • `` -> `...8`
#> • `` -> `...9`
#> • `` -> `...10`
#> • `` -> `...11`
#> • `` -> `...13`
#> • `` -> `...14`
#> • `` -> `...15`
#> • `` -> `...16`
colnames(f4h) <-
    c("Days", rep(
        c("PBS", "SLAMF6+ PD-1+ CD8+ cells", "SLAMF6- PD-1+ CD8+ cells"),
        each = 5
    ))

f4h |> pivot_longer(cols = -1,
                    names_to = "method",
                    values_to = "volume",) |>
    dplyr::mutate(id=factor(rep(1:15,3)),
                  Days = factor(Days, levels = c("-1", "7", "14")),
                  method = factor(
                      method,
                      levels = c("PBS", "SLAMF6+ PD-1+ CD8+ cells",
                                 "SLAMF6- PD-1+ CD8+ cells")
                  )) -> f4h
f4h
#> # A tibble: 45 × 4
#>    Days  method                   volume id   
#>    <fct> <fct>                     <dbl> <fct>
#>  1 -1    PBS                        19.2 1    
#>  2 -1    PBS                        27.0 2    
#>  3 -1    PBS                        23.4 3    
#>  4 -1    PBS                        27.9 4    
#>  5 -1    PBS                        29.7 5    
#>  6 -1    SLAMF6+ PD-1+ CD8+ cells   31.9 6    
#>  7 -1    SLAMF6+ PD-1+ CD8+ cells   34.5 7    
#>  8 -1    SLAMF6+ PD-1+ CD8+ cells   44.4 8    
#>  9 -1    SLAMF6+ PD-1+ CD8+ cells   29.1 9    
#> 10 -1    SLAMF6+ PD-1+ CD8+ cells   41.4 10   
#> # ℹ 35 more rows

统计p值

Code
# 重复测量方差设计
library(nlme)
model <- lme(volume ~ method*Days, random = ~1|id/Days, data = f4h)
summary(model)
#> Linear mixed-effects model fit by REML
#>   Data: f4h 
#>        AIC      BIC    logLik
#>   305.8048 324.8071 -140.9024
#> 
#> Random effects:
#>  Formula: ~1 | id
#>         (Intercept)
#> StdDev:    6.775335
#> 
#>  Formula: ~1 | Days %in% id
#>         (Intercept) Residual
#> StdDev:    6.775335 2.540755
#> 
#> Fixed effects:  volume ~ method * Days 
#>                                           Value Std.Error DF   t-value p-value
#> (Intercept)                            25.43718  4.433188 36  5.737899  0.0000
#> methodSLAMF6+ PD-1+ CD8+ cells         10.81993  6.269474 36  1.725812  0.0930
#> methodSLAMF6- PD-1+ CD8+ cells          4.63341  6.269474 36  0.739043  0.4647
#> Days7                                   9.55505  6.269474 36  1.524059  0.1362
#> Days14                                 22.41864  6.269474 36  3.575841  0.0010
#> methodSLAMF6+ PD-1+ CD8+ cells:Days7  -37.58056  8.866375 36 -4.238549  0.0001
#> methodSLAMF6- PD-1+ CD8+ cells:Days7   -8.90525  8.866375 36 -1.004384  0.3219
#> methodSLAMF6+ PD-1+ CD8+ cells:Days14 -55.79891  8.866375 36 -6.293316  0.0000
#> methodSLAMF6- PD-1+ CD8+ cells:Days14 -14.68420  8.866375 36 -1.656167  0.1064
#>  Correlation: 
#>                                       (Intr) mtSLAMF6+PD-1+CD8+c
#> methodSLAMF6+ PD-1+ CD8+ cells        -0.707                    
#> methodSLAMF6- PD-1+ CD8+ cells        -0.707  0.500             
#> Days7                                 -0.707  0.500             
#> Days14                                -0.707  0.500             
#> methodSLAMF6+ PD-1+ CD8+ cells:Days7   0.500 -0.707             
#> methodSLAMF6- PD-1+ CD8+ cells:Days7   0.500 -0.354             
#> methodSLAMF6+ PD-1+ CD8+ cells:Days14  0.500 -0.707             
#> methodSLAMF6- PD-1+ CD8+ cells:Days14  0.500 -0.354             
#>                                       mtSLAMF6-PD-1+CD8+c Days7  Days14
#> methodSLAMF6+ PD-1+ CD8+ cells                                         
#> methodSLAMF6- PD-1+ CD8+ cells                                         
#> Days7                                  0.500                           
#> Days14                                 0.500               0.500       
#> methodSLAMF6+ PD-1+ CD8+ cells:Days7  -0.354              -0.707 -0.354
#> methodSLAMF6- PD-1+ CD8+ cells:Days7  -0.707              -0.707 -0.354
#> methodSLAMF6+ PD-1+ CD8+ cells:Days14 -0.354              -0.354 -0.707
#> methodSLAMF6- PD-1+ CD8+ cells:Days14 -0.707              -0.354 -0.707
#>                                       mSLAMF6+PD-1+CD8+c:D7
#> methodSLAMF6+ PD-1+ CD8+ cells                             
#> methodSLAMF6- PD-1+ CD8+ cells                             
#> Days7                                                      
#> Days14                                                     
#> methodSLAMF6+ PD-1+ CD8+ cells:Days7                       
#> methodSLAMF6- PD-1+ CD8+ cells:Days7   0.500               
#> methodSLAMF6+ PD-1+ CD8+ cells:Days14  0.500               
#> methodSLAMF6- PD-1+ CD8+ cells:Days14  0.250               
#>                                       mSLAMF6-PD-1+CD8+c:D7
#> methodSLAMF6+ PD-1+ CD8+ cells                             
#> methodSLAMF6- PD-1+ CD8+ cells                             
#> Days7                                                      
#> Days14                                                     
#> methodSLAMF6+ PD-1+ CD8+ cells:Days7                       
#> methodSLAMF6- PD-1+ CD8+ cells:Days7                       
#> methodSLAMF6+ PD-1+ CD8+ cells:Days14  0.250               
#> methodSLAMF6- PD-1+ CD8+ cells:Days14  0.500               
#>                                       mSLAMF6+PD-1+CD8+c:D1
#> methodSLAMF6+ PD-1+ CD8+ cells                             
#> methodSLAMF6- PD-1+ CD8+ cells                             
#> Days7                                                      
#> Days14                                                     
#> methodSLAMF6+ PD-1+ CD8+ cells:Days7                       
#> methodSLAMF6- PD-1+ CD8+ cells:Days7                       
#> methodSLAMF6+ PD-1+ CD8+ cells:Days14                      
#> methodSLAMF6- PD-1+ CD8+ cells:Days14  0.500               
#> 
#> Standardized Within-Group Residuals:
#>         Min          Q1         Med          Q3         Max 
#> -0.54102103 -0.09310952 -0.02293325  0.11100673  0.62463379 
#> 
#> Number of Observations: 45
#> Number of Groups: 
#>           id Days %in% id 
#>           45           45
df_aov <- anova(model)
df_aov
#>             numDF denDF  F-value p-value
#> (Intercept)     1    36 365.4570  <.0001
#> method          2    36  18.1753  <.0001
#> Days            2    36   1.5292  0.2305
#> method:Days     4    36  11.1001  <.0001

#成对比较
library(emmeans)
#> Welcome to emmeans.
#> Caution: You lose important information if you filter this package's results.
#> See '? untidy'
method_means <- emmeans(model, ~method)  
#> NOTE: Results may be misleading due to involvement in interactions
print(method_means)  
#>  method                   emmean   SE df lower.CL upper.CL
#>  PBS                        36.1 2.56 36     30.9     41.3
#>  SLAMF6+ PD-1+ CD8+ cells   15.8 2.56 36     10.6     21.0
#>  SLAMF6- PD-1+ CD8+ cells   32.9 2.56 36     27.7     38.1
#> 
#> Results are averaged over the levels of: Days 
#> Degrees-of-freedom method: containment 
#> Confidence level used: 0.95
method_comparisons <- pairs(method_means)  
method_comparisons
#>  contrast                                                estimate   SE df
#>  PBS - (SLAMF6+ PD-1+ CD8+ cells)                           20.31 3.62 36
#>  PBS - (SLAMF6- PD-1+ CD8+ cells)                            3.23 3.62 36
#>  (SLAMF6+ PD-1+ CD8+ cells) - (SLAMF6- PD-1+ CD8+ cells)   -17.08 3.62 36
#>  t.ratio p.value
#>    5.610  <.0001
#>    0.892  0.6486
#>   -4.718  0.0001
#> 
#> Results are averaged over the levels of: Days 
#> Degrees-of-freedom method: containment 
#> P value adjustment: tukey method for comparing a family of 3 estimates

2 ggplot2

Code
pvalue <- method_comparisons |> broom::tidy() |> 
    dplyr::select(contrast, adj.p.value) |> 
    dplyr::mutate(padj=round(adj.p.value,digits = 4),
                  p_adj_sci=format(adj.p.value,scientific = T,digits = 4))

pvalue
#> # A tibble: 3 × 4
#>   contrast                                          adj.p.value   padj p_adj_sci
#>   <chr>                                                   <dbl>  <dbl> <chr>    
#> 1 PBS - (SLAMF6+ PD-1+ CD8+ cells)                   0.00000680 0      6.796e-06
#> 2 PBS - (SLAMF6- PD-1+ CD8+ cells)                   0.649      0.649  6.486e-01
#> 3 (SLAMF6+ PD-1+ CD8+ cells) - (SLAMF6- PD-1+ CD8+…  0.000103   0.0001 1.032e-04

p <- f4h |> summarise(
    mean_volume = mean(volume),
    sd = sd(volume),
    .by = c(Days, method),) |>
    ggplot(aes(
        x = Days,
        y = mean_volume,
        color = method,
        group = method,)) +
    geom_errorbar(
        aes(ymin = mean_volume - sd, ymax = mean_volume + sd),
        position = position_dodge(0),
        width = .2,
        linewidth = 0.5,
    ) +
    geom_line(position = position_dodge(0),
              linewidth = 0.8) +
    geom_point(
        aes(shape = method),
        position = position_dodge(0),
        color = "black",
        size = 2) +
    theme_pubr() +
    theme(legend.title = element_blank())

# 使用ggplot_build()获取图层数据
plot_data <- ggplot_build(p)

# 查看X轴的数值坐标
plot_data$data
#> [[1]]
#>    colour       ymin      ymax x         y group PANEL flipped_aes      xmin
#> 1 #F8766D 21.2341315 29.640231 1 25.437181     1     1       FALSE 0.9666667
#> 2 #00BA38 29.8251093 42.689121 1 36.257115     2     1       FALSE 0.9666667
#> 3 #619CFF 23.2386460 36.902540 1 30.070593     3     1       FALSE 0.9666667
#> 4 #F8766D 20.3358912 49.648564 2 34.992228     1     1       FALSE 1.9666667
#> 5 #00BA38  4.8856152 11.577581 2  8.231598     2     1       FALSE 1.9666667
#> 6 #619CFF 22.3836755 39.057109 2 30.720392     3     1       FALSE 1.9666667
#> 7 #F8766D 28.7160676 66.995581 3 47.855824     1     1       FALSE 2.9666667
#> 8 #00BA38  0.5880804  5.165626 3  2.876853     2     1       FALSE 2.9666667
#> 9 #619CFF 27.2406302 48.369439 3 37.805035     3     1       FALSE 2.9666667
#>       xmax linewidth linetype width alpha
#> 1 1.033333       0.5        1   0.2    NA
#> 2 1.033333       0.5        1   0.2    NA
#> 3 1.033333       0.5        1   0.2    NA
#> 4 2.033333       0.5        1   0.2    NA
#> 5 2.033333       0.5        1   0.2    NA
#> 6 2.033333       0.5        1   0.2    NA
#> 7 3.033333       0.5        1   0.2    NA
#> 8 3.033333       0.5        1   0.2    NA
#> 9 3.033333       0.5        1   0.2    NA
#> 
#> [[2]]
#>    colour x         y group PANEL flipped_aes xmin xmax      ymax linewidth
#> 1 #F8766D 1 25.437181     1     1       FALSE    1    1 25.437181       0.8
#> 2 #F8766D 2 34.992228     1     1       FALSE    2    2 34.992228       0.8
#> 3 #F8766D 3 47.855824     1     1       FALSE    3    3 47.855824       0.8
#> 4 #00BA38 1 36.257115     2     1       FALSE    1    1 36.257115       0.8
#> 5 #00BA38 2  8.231598     2     1       FALSE    2    2  8.231598       0.8
#> 6 #00BA38 3  2.876853     2     1       FALSE    3    3  2.876853       0.8
#> 7 #619CFF 1 30.070593     3     1       FALSE    1    1 30.070593       0.8
#> 8 #619CFF 2 30.720392     3     1       FALSE    2    2 30.720392       0.8
#> 9 #619CFF 3 37.805035     3     1       FALSE    3    3 37.805035       0.8
#>   linetype alpha
#> 1        1    NA
#> 2        1    NA
#> 3        1    NA
#> 4        1    NA
#> 5        1    NA
#> 6        1    NA
#> 7        1    NA
#> 8        1    NA
#> 9        1    NA
#> 
#> [[3]]
#>   shape x         y group PANEL xmin xmax      ymax colour size fill alpha
#> 1    16 1 25.437181     1     1    1    1 25.437181  black    2   NA    NA
#> 2    17 1 36.257115     2     1    1    1 36.257115  black    2   NA    NA
#> 3    15 1 30.070593     3     1    1    1 30.070593  black    2   NA    NA
#> 4    16 2 34.992228     1     1    2    2 34.992228  black    2   NA    NA
#> 5    17 2  8.231598     2     1    2    2  8.231598  black    2   NA    NA
#> 6    15 2 30.720392     3     1    2    2 30.720392  black    2   NA    NA
#> 7    16 3 47.855824     1     1    3    3 47.855824  black    2   NA    NA
#> 8    17 3  2.876853     2     1    3    3  2.876853  black    2   NA    NA
#> 9    15 3 37.805035     3     1    3    3 37.805035  black    2   NA    NA
#>   stroke
#> 1    0.5
#> 2    0.5
#> 3    0.5
#> 4    0.5
#> 5    0.5
#> 6    0.5
#> 7    0.5
#> 8    0.5
#> 9    0.5



p  +  annotate(geom = "segment",
               x = 3.4,
               y = 47.855824,
               yend = 2.876853,) + annotate(
                   geom = "text",
                   x = 3.45,
                   y = (47.855824 + 2.876853) / 2,
                   angle = 270,
                   label = pvalue$padj[1],
               ) +
    annotate(geom = "segment",
             x = 3.15,
             y = 47.855824,
             yend = 37.805035,) + annotate(
                 geom = "text",
                 x = 3.2,
                 y = (47.855824 + 37.805035) / 2,
                 angle = 270,
                 label = pvalue$padj[2],
             ) +
    annotate(geom = "segment",
             x = 3.3,
             y = 2.876853,
             yend = 37.805035,) + annotate(
                 geom = "text",
                 x = 3.35,
                 y = (2.876853 + 37.805035) / 2,
                 angle = 270,
                 label = pvalue$padj[3],
             )

Code

#y=c(47.855824,37.805035,2.876853,),
#yend = c(2.876853,47.855824,37.805035,),

https://www.datanovia.com/en/blog/how-to-add-p-values-onto-a-grouped-ggplot-using-the-ggpubr-r-package/

3 ggpubr

Code
df <- ToothGrowth
df$dose <- as.factor(df$dose)

stat.test <- df %>%
    group_by(dose) %>%
    t_test(len ~ supp) %>%
    adjust_pvalue(method = "bonferroni") %>%
    add_significance("p.adj")


lp <- ggline(
    df,
    x = "dose",
    y = "len",
    add = "mean_sd",
    color = "supp",
    palette = c("#00AFBB", "#E7B800")
)
lp

Code
# Add p-values onto the line plots
# Remove brackets using linetype = "blank"
stat.test <- stat.test %>%
    add_xy_position(fun = "mean_sd", x = "dose")
lp + stat_pvalue_manual(stat.test,
                        label = "p.adj.signif",
                        tip.length = 0,
                        linetype  = "blank")

Back to top