Load required packages

library(dplyr) library(readr) library(openxlsx)

Define path

path <-
“/Users/....IFITM3_SL1/outputA549/”

Get all subfolder paths

subfolders <- list.dirs(path, full.names = TRUE, recursive = FALSE)

Initialize an empty data frame

merged_data <- data.frame()

Loop through abundance.tsv files in each subfolder

for (subfolder in subfolders) { #

folder_name <- basename(subfolder)

# abundance.tsv

file_path <- file.path(subfolder, “abundance.tsv”) if
(file.exists(file_path)) { data <- read_tsv(file_path)

    # Keep only target_id and est_counts columns

    data <- data %>% select(target_id, est_counts)

    #  est_counts 

    colnames(data)[colnames(data) == "est_counts"] <- folder_name

    #  merged_data ，

    if (nrow(merged_data) == 0) {
      merged_data <- data

    } else {
      # 

      merged_data <- merge(merged_data, data, by = "target_id", all = TRUE)
    }

} }

Export merged data frame as Excel file

output_file <- file.path(path, “merged_output.xlsx”)
write.xlsx(merged_data, output_file)
############################################################################
#### ############## # Calculate each column（ folder_name ）
total_counts <- colSums(merged_data[, -1], na.rm = TRUE) # Create new
columns， for (col in colnames(merged_data)[2:ncol(merged_data)]) {
ratio_col_name <- paste0(col, “_ratio”) merged_data[[ratio_col_name]] <-
merged_data[[col]] / total_counts[col]} # Export merged data frame as
Excel file output_file <- file.path(path,
“merged_output_with_ratios.xlsx”) write.xlsx(merged_data, output_file)
############################################################################
#### ############### # id original-value ratio original_value_row <-
merged_data[merged_data$target_id == "SL1_original",
]
# Create new columns， folder_name_ratio  original-value
ratio
for (col in colnames(merged_data)[3:ncol(merged_data)]) {
  if (grepl("_ratio$“, col)) { original_value_ratio <-
original_value_row[[col]] rf_col_name <- paste0(gsub(”_ratio$“,”“,
col),”_RF”) merged_data[[rf_col_name]] <- merged_data[[col]] /
original_value_ratio}} # Export merged data frame as Excel file
output_file <- file.path(path, “merged_output_RF.xlsx”)
write.xlsx(merged_data, output_file)
############################################################################
#### ######################## # Calculate each column（ _RF ） stock

for (col in colnames(merged_data)[3:ncol(merged_data)]) { if
(grepl(“_RF$“, col)) { stock_col_name <-”SL1-plasmid_output_RF”
stock_col <- merged_data[[stock_col_name]] new_col_name <- paste0(col,
“_plasmid_RF”) merged_data[[new_col_name]] <- merged_data[[col]] /
stock_col}} # Excel output_file <- file.path(path,
“merged_output_final.xlsx”) write.xlsx(merged_data, output_file)

######sl1############################# library(readxl) library(tidyr)
library(dplyr) library(ggplot2) library(matrixStats) ##### # Read the
CSV file ratioRF <-
read_excel(“/Users/.../merged_output_RF.xlsx”)
############# MOCK_cols <- as.matrix(ratioRF[c(46:48)]) PR8_cols <-
as.matrix(ratioRF[c(55:57)]) WSN_cols <- as.matrix(ratioRF[c(64:66)])
PR8_GFP_pos_cols <- as.matrix(ratioRF[c(52:54)]) PR8_GFP_neg_cols <-
as.matrix(ratioRF[c(49:51)]) WSN_GFP_pos_cols <-
as.matrix(ratioRF[c(61:63)]) WSN_GFP_neg_cols <-
as.matrix(ratioRF[c(58:60)])

ratioRFMOCKAvg < −rowMeans(MOCK_(c)ols)ratioRFPR8Avg <-
rowMeans(PR8_cols)
ratioRFWSNAvg < −rowMeans(WSN_(c)ols)ratioRFPR8_GFP_posAvg <-
rowMeans(PR8_GFP_pos_cols)
ratioRFPR8_(G)FP_(n)egAvg < −rowMeans(PR8_(G)FP_(n)eg_(c)ols)ratioRFWSN_GFP_posAvg
<- rowMeans(WSN_GFP_pos_cols)
ratioRFWSN_(G)FP_(n)egAvg < −rowMeans(WSN_(G)FP_(n)eg_(c)ols)ratioRFMOCKSD
<- apply(MOCK_cols, 1, sd) / ratioRFMOCKAvgratioRFPR8SD <-
apply(PR8_cols, 1, sd) / ratioRFPR8AvgratioRFWSNSD <- apply(WSN_cols, 1,
sd) / ratioRFWSNAvgratioRFPR8_GFP_posSD <- apply(PR8_GFP_pos_cols, 1,
sd) / ratioRFPR8_(G)FP_(p)osAvgratioRFPR8_GFP_negSD <-
apply(PR8_GFP_neg_cols, 1, sd) /
ratioRFPR8_(G)FP_(n)egAvgratioRFWSN_GFP_posSD <- apply(WSN_GFP_pos_cols,
1, sd) / ratioRFWSN_(G)FP_(p)osAvgratioRFWSN_GFP_negSD <-
apply(WSN_GFP_neg_cols, 1, sd) / ratioRF$WSN_GFP_negAvg

#ratioRF_filteredX < −gsub(′sublib47 − ′, ″, ratioRF_(f)ilteredX)
#ratioRF_filtered <- separate(ratioRF_filtered, X, sep = “_“, into =
c(‘AA’, ‘Residue’)) output_file <-
file.path(path,”merged_output_filtered.xlsx”) write.xlsx(ratioRF,
output_file) #############

ratioRFFC_(P)R8GFP_(p)os_(n)eg < −ratioRFPR8_GFP_negAvg /
ratioRF$PR8_GFP_posAvg

ratioRFFC_(W)SNGFP_(p)os_(n)eg < −ratioRFWSN_GFP_negAvg /
ratioRF$WSN_GFP_posAvg

ratioRFtarget_(i)d < −gsub(′SL1_(′), ″, ratioRFtarget_id) ratioRF <-
ratioRF %>% separate(target_id, into = c(“AA_ref”, “position”,
“AA_var”), sep = “_“)

##########。 Plotting # position
ratioRFposition < −as.numeric(ratioRFposition)

ggplot(ratioRF, aes(x = position, y = FC_WSNGFP_pos_neg, color =
AA_var)) + geom_point(alpha = 0.6, size = 2) + # labs(x = “Position”, y
= “FC_PR8GFP_pos/neg”, title = “Fold Change by Position and Amino
Acid”) + scale_color_discrete(name = “AA Mutation”) + #
theme_minimal(base_size = 12) + theme( legend.position = “right”,
panel.grid.major = element_line(color = “grey90”), panel.grid.minor =
element_blank() ) + geom_hline(yintercept = 1, linetype = “dashed”,
color = “red”) + ylim(0.2, 3) # ######

library(readxl) library(tidyr) library(dplyr) library(ggplot2)
library(openxlsx) cj1 <-
read_excel(“/Users/...merged_output_combined_filtered.xlsx”) cj2 <-
read_excel(‘/Users/...SL2_A549/merged_output_combined_filtered.xlsx’)

target_id target_id2

cj1target_(i)d2 < −cj1target_id

cj2target_(i)d2 < −cj2target_id # ‘sublib48-’ X
cj1target_(i)d < −gsub(′SL1_(′), ″, cj1target_id)
cj2target_(i)d < −gsub(′SL2_(′), ″, cj2target_id)

X AA2 Residue2

cj1 <- cj1 %>% separate(target_id, into = c(“AA_ref”, “position”,
“AA_var”), sep = “”) cj2 <- cj2 %>% separate(target_id, into =
c(”AA_ref”, ”position”, ”AA_var”), sep = ””)

AA2

cj1position < −as.numeric(as.character(cj1position))
cj2position < −as.numeric(as.character(cj2position)) # cj2，position<=7

cj2_filtered <- cj2 %>% filter(position > 7)

cj1position < −cj1position
cj2_filteredposition < −cj2_(f)ilteredposition + 63

cj cj1， AA2

cj_merged <- bind_rows(cj1, cj2_filtered) %>% arrange(position) %>%
select(AA_ref,position,
AA_var,target_id2,MOCKAvg,PR8Avg,WSNAvg,PR8_GFP_posAvg,PR8_GFP_negAvg,WSN_GF
P_posAvg, WSN_GFP_negAvg,H7N9_GFP_negAvg,H7N9_GFP_posAvg) # Residue2 DEL
STOP #cj_merged <- cj_merged %>% # filter(!(Residue2 %in% c(“DEL”,
“STOP”))) cj_mergedFC_(P)R8GFP_(n)eg_(p)os < −cj_(m)ergedPR8_GFP_negAvg
/ cj_mergedPR8_(G)FP_(p)osAvgcj_(m)ergedFC_WSNGFP_neg_pos <-
cj_mergedWSN_(G)FP_(n)egAvg/cj_(m)ergedWSN_GFP_posAvg
cj_mergedFC_(H)7N9GFP_(n)eg_(p)os < −cj_(m)ergedH7N9_GFP_negAvg /
cj_merged$H7N9_GFP_posAvg

path <-
“/Users/..../3virus_analysis/”

output_file <- file.path(path, “merged_A549.xlsx”) write.xlsx(cj_merged,
output_file)

##########。 Plotting ################### cj_merged <-
read_excel(“/Users/.../merged_A549.xlsx”)

figure1。

#position cj_mergedposition < −as.numeric(cj_(m)ergedposition)

ggplot(cj_merged, aes(x = position, y = FC_PR8GFP_neg_pos, color =
AA_var)) + geom_point(alpha = 0.6, size = 2) + # labs(x = “Position”, y
= “FC_PR8GFP_pos/neg”, title = “Fold Change by Position and Amino
Acid”) + scale_color_discrete(name = “AA Mutation”) + #
theme_minimal(base_size = 12) + theme( legend.position = “right”,
panel.grid.major = element_line(color = “grey90”), panel.grid.minor =
element_blank() ) + geom_hline(yintercept = 1, linetype = “dashed”,
color = “red”) + ylim(0.2, 3) # ###### ##

#。。。。histogram 1. （ AA_var） #2. “STOP”#3. “DEL” #4. “SYN”

library(ggplot2) library(ggsci) library(dplyr) library(gridExtra)

Nature

theme_nature <- theme_minimal(base_size = 14) + theme( text =
element_text(face = “bold”), axis.title = element_text(‘none’),
axis.text = element_text(face = “bold”), panel.grid.major =
element_line(color = “grey90”), panel.grid.minor = element_blank() )

4

all_mut <- cj_merged stop_mut <- cj_merged %>% filter(AA_var == “STOP”)
del_mut <- cj_merged %>% filter(AA_var == “DEL”) syn_mut <- cj_merged
%>% filter(AA_var == “SYN”)

histogram（x = FC_PR8GFP_neg_pos）

p1 <- ggplot(syn_mut, aes(x = FC_PR8GFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#3C5488”, color = “black”, alpha
= 0.85) + labs(title = “SYN Mutations”, x = “FC_PR8GFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p2 <- ggplot(stop_mut, aes(x = FC_PR8GFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#E64B35”, color = “black”, alpha
= 0.85) + labs(title = “STOP Mutations”, x = “FC_PR8GFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p3 <- ggplot(del_mut, aes(x = FC_PR8GFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#00A087”, color = “black”, alpha
= 0.85) + labs(title = “DEL Mutations”, x = “FC_PR8GFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p4 <- ggplot(all_mut, aes(x = FC_PR8GFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#4DBBD5”, color = “black”, alpha
= 0.85) + labs(title = “All Mutations”, x = “FC_PR8GFP_neg_pos”, y =
“Count”) + xlim(0, 2) + # theme_nature

grid.arrange(p1, p2, p3, p4, ncol = 1)

histogram（x = FC_PR8GFP_neg_pos）

p1 <- ggplot(syn_mut, aes(x = FC_WSNGFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#3C5488”, color = “black”, alpha
= 0.85) + labs(title = “SYN Mutations”, x = “FC_WSNGFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p2 <- ggplot(stop_mut, aes(x = FC_WSNGFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#E64B35”, color = “black”, alpha
= 0.85) + labs(title = “STOP Mutations”, x = “FC_WSNGFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p3 <- ggplot(del_mut, aes(x = FC_WSNGFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#00A087”, color = “black”, alpha
= 0.85) + labs(title = “DEL Mutations”, x = “FC_WSNGFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p4 <- ggplot(all_mut, aes(x = FC_WSNGFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill =“#4DBBD5” , color = “black”, alpha
= 0.85) + labs(title = “All Mutations”, x = “FC_WSNGFP_neg_pos”, y =
“Count”) + xlim(0, 2) + # theme_nature

grid.arrange(p1, p2, p3, p4, ncol = 1)

histogram（x = FC_H7N9GFP_neg_pos）

p1 <- ggplot(syn_mut, aes(x = FC_H7N9GFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#3C5488”, color = “black”, alpha
= 0.85) + labs(title = “SYN Mutations”, x = “FC_H7N9GFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p2 <- ggplot(stop_mut, aes(x = FC_H7N9GFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#E64B35”, color = “black”, alpha
= 0.85) + labs(title = “STOP Mutations”, x = “FC_H7N9GFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p3 <- ggplot(del_mut, aes(x = FC_H7N9GFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill = “#00A087”, color = “black”, alpha
= 0.85) + labs(title = “DEL Mutations”, x = “FC_H7N9GFP_neg_pos”, y =
“Count”) + xlim(0, 2) + theme_nature

p4 <- ggplot(all_mut, aes(x = FC_H7N9GFP_neg_pos)) +
geom_histogram(binwidth = 0.1, fill =“#4DBBD5” , color = “black”, alpha
= 0.85) + labs(title = “All Mutations”, x = “FC_H7N9GFP_neg_pos”, y =
“Count”) + xlim(0, 2) + # theme_nature

grid.arrange(p1, p2, p3, p4, ncol = 1)

######。 Horizontal violin and density plots。

library(ggplot2) library(ggbeeswarm) library(patchwork)

===============================

（Nature ）

===============================

nature_violin_colors <- c( “SYN” = “#E6E4D8”, “DEL” = “#A7D7B4”, “STOP”
= “#F6B3A2”, “Missense” = “#9FD3F0” )

nature_point_colors <- c( “SYN” = “#E6E4D8”, “DEL” = “#A7D7B4”, “STOP” =
“#F6B3A2”, “Missense” = “#9FD3F0” )

===============================

：（ = FC）

===============================

p_density <- ggplot( cj_merged, aes( x = FC_WSNGFP_neg_pos, fill =
mut_type, color = mut_type ) ) + geom_density( size = 0.8, alpha = 0.25
) + scale_fill_manual(values = nature_violin_colors) +
scale_color_manual(values = nature_point_colors) + coord_cartesian(xlim
= c(0, 3)) + theme_minimal(base_size = 14) + theme( axis.title =
element_blank(), axis.text.y = element_blank(), axis.ticks.y =
element_blank(), axis.text.x = element_blank(), axis.ticks.x =
element_blank(), panel.grid = element_blank(), legend.position = “none”
)

===============================

： +

===============================

p_violin <- ggplot( cj_merged, aes( y = mut_type, x = FC_PR8GFP_neg_pos
) ) + geom_violin( aes(fill = mut_type), trim = FALSE, scale = “width”,
alpha = 0.8, color = NA ) + geom_quasirandom( aes(fill = mut_type),
shape = 21, color = “black”, stroke = 0.3, width = 0.25, size = 1.0,
alpha = 0.7 ) + scale_fill_manual(values = nature_violin_colors) +
coord_cartesian(xlim = c(0, 3)) + labs( x = “Fold Change (Fitness)”, y =
“Mutation Type” ) + theme_minimal(base_size = 14) + theme( axis.text.x =
element_text(color = “black”,face = ‘bold’), axis.text.y =
element_text(color = “black”,face = ‘bold’), axis.title.x =
element_text(color = “black”,face = ‘bold’), axis.title.y =
element_text(color = “black”,face = ‘bold’),

    axis.ticks   = element_line(color = "black"),
    panel.border = element_rect(
      color = "black",
      fill  = NA,
      linewidth = 0.6
    ),

    axis.line = element_blank(),  #  panel.border 

    panel.grid = element_blank(),
    legend.position = "none"

)

===============================

： /

===============================

p_density / p_violin + plot_layout(heights = c(1, 4))

#。 。。 figure2. Heatmap showing amino acid effects。

library(tidyr) library(dplyr) library(ggplot2) library(scales)
library(readxl)

===============================

Read data

===============================

cj_merged <- readxl::read_excel(

“/Users/.../merged_
A549.xlsx” )

===============================

Prepare plotting data

===============================

plot_data <- cj_merged %>% select( position, AA_ref, AA_var,
FC_PR8GFP_neg_pos, FC_WSNGFP_neg_pos, FC_H7N9GFP_neg_pos ) %>%
filter(!is.na(AA_var) & AA_ref != “original”) %>% mutate(position =
as.integer(position))

===============================

Define amino acid order

===============================

aa_levels <- c( “A”,“C”,“D”,“E”,“F”,“G”,“H”,“I”,“K”,“L”,
“M”,“N”,“P”,“Q”,“R”,“S”,“T”,“V”,“W”,“Y”, “STOP”,“DEL”,“SYN” )

===============================

WT sequence（1–133）

===============================

wt_seq <- strsplit(

“MNHTVQTFFSPVNSGQPPNYEMLKEEHEVAVLGAPHNPAPPTSTVIHIRSETSVPDHVVWSLFNTLFMNPCCLGF
IAFAYSVKSRDRKMVGDVTGAQAYASTAKCLNIWALILGILMTILLIVIPVLIFQAYG”, “” )[[1]]

wt_df <- tibble( position = seq_along(wt_seq), AA_var = wt_seq ) %>%
mutate( AA_var = factor(AA_var, levels = aa_levels) )

===============================

（ WT ）

===============================

create_heatmap <- function(data, fc_column, title) {

# plot_df <- data %>% select(position, AA_var, fc_value =
all_of(fc_column)) %>% mutate( fc_value = case_when( fc_value < 0.01 ~
0.01, fc_value > 10 ~ 10, is.na(fc_value) ~ 0.01, TRUE ~ fc_value ),
AA_var = factor(AA_var, levels = aa_levels), AA_var = droplevels(AA_var)
)

# （log10） color_breaks <- c(0.5, 1, 2) color_values <-
rescale(log10(color_breaks)) nature_colors <- c(“#982b2b”, “#F8F8F8”,
“#0074b3”)

p <- ggplot(plot_df, aes(x = position, y = AA_var, fill = fc_value)) +

    geom_tile(color = "grey70", linewidth = 0.2) +

    geom_text(
      data = wt_df,
      aes(x = position, y = AA_var),
      label = "*",
      color = "black",
      size = 10.5,
      inherit.aes = FALSE
    ) +

    scale_fill_gradientn(
      name = "Fold Change",
      colours = nature_colors,
      values = color_values,
      limits = c(0.5, 2),
      trans = "log10",
      oob = scales::squish,
      breaks = color_breaks,
      labels = c("0.5", "1", "2")
    ) +

    scale_x_continuous(
      expand = c(0, 0),
      breaks = c(1, 20, 40, 60, 80, 100, 120, 133),
      labels = c("1", "20", "40", "60", "80", "100", "120", "133")
    ) +

    scale_y_discrete(expand = c(0, 0), drop = TRUE) +

    theme_minimal(base_size = 14) +
    theme(
      axis.text.x = element_text(
        angle = 0, vjust = 0.5, hjust = 1,
        size = 24, face = "bold",colour = "black"
      ),
      axis.text.y = element_text(size = 24, face = "bold", colour =

“black”), axis.title = element_text(size = 28, face = “bold”,colour =
“black”), legend.text = element_text(size = 24, face = “bold”,colour =
“black”), legend.title = element_text(size = 24, face = “bold”,colour =
“black”), legend.position = “bottom”, legend.key.width = unit(0.8,
“cm”), panel.grid = element_blank(), panel.background =
element_rect(fill = “grey95”, colour = NA), plot.title =
element_text(hjust = 0.5, size = 18, face = “bold”,colour = “black”) )

return(p) }

===============================

Generate three heatmaps

===============================

p1 <- create_heatmap(plot_data, “FC_PR8GFP_neg_pos”, “PR8 GFP- vs GFP+”)
p2 <- create_heatmap(plot_data, “FC_WSNGFP_neg_pos”, “WSN GFP- vs GFP+”)
p3 <- create_heatmap(plot_data, “FC_H7N9GFP_neg_pos”, “H7N9 GFP- vs
GFP+”)

===============================

Print output

===============================

print(p1) print(p2) print(p3)

############。gnomAD 。

#。 step1。First process。gnomAD 。 # ===============================
library(dplyr) library(stringr) library(readr)

file <-
“/Users/.../gnomAD_
v4.1.0_IFITM3_filtered.csv” df <- read_csv(file)

→

aa3to1 <- c( Ala=“A”, Arg=“R”, Asn=“N”, Asp=“D”, Cys=“C”, Gln=“Q”,
Glu=“E”, Gly=“G”, His=“H”, Ile=“I”, Leu=“L”, Lys=“K”, Met=“M”, Phe=“F”,
Pro=“P”, Ser=“S”, Thr=“T”, Trp=“W”, Tyr=“Y”, Val=“V”, Ter=“*“, Sec=”U” )

safe_convert <- function(x) { if (is.na(x)) return(NA) if (x %in%
names(aa3to1)) return(aa3to1[[x]]) return(NA) }

parse_consequence <- function(x) {

# NA p. → NA if (is.na(x) || !str_detect(x, “p\.”)) {
return(data.frame(AA_ref = NA, position = NA, AA_var = NA)) }

# p. x <- str_replace(x, “^p\.”, ““)

# ext if (str_detect(x, “ext”)) { ref3 <- str_extract(x, “[1]+”) pos <-
str_extract(x, “(?<=[2]{3})[0-9]+”) ref1 <- safe_convert(ref3)
return(data.frame( AA_ref = ref1, position = pos, AA_var = “STOP” )) }

# ref3 <- str_extract(x, “[3]+”) pos <- str_extract(x, “[0-9]+”) var3 <-
str_extract(x, “[A-Za-z]+$”)

ref1 <- safe_convert(ref3)

# var3 “del” → “DEL” if (!is.na(var3) && str_to_lower(var3) == “del”) {
var1 <- “DEL” } else { var1 <- safe_convert(var3) # SYN if (!is.na(ref1)
&& !is.na(var1) && ref1 == var1) { var1 <- “SYN” } }

return(data.frame( AA_ref = ref1, position = pos, AA_var = var1 )) }

parsed <- bind_rows(lapply(df$Protein Consequence, parse_consequence))

df2 <- bind_cols(df, parsed)

“*” STOP

df2 <- df2 %>% mutate( AA_ref = ifelse(AA_ref == “”, ”STOP”, AA_ref),
AA_var = ifelse(AA_var == ””, “STOP”, AA_var) )

write_csv(df2,
“/Users/.../gnomAD_
v4.1.0_IFITM3_filtered_parsed.csv”)

######。 step2 match gnomAD， # Load required packages # Load required
packages () library(dplyr) library(readr) library(readxl)
library(ggplot2) library(tidyr) library(gridExtra)

===============================

1. gnomAD

library(readr) library(dplyr) library(janitor)

gnomad <- read_csv(

“/Users/chenjian9007163.com/Desktop/bk/IFITM3library/3virus_analysis/gnomAD_
v4.1.0_IFITM3_filtered_parsed.csv”, show_col_types = FALSE ) %>%
clean_names()

===============================

2.

===============================

mydata_file <-
“/Users/.../merged_
293T.xlsx” mydata <- read_excel(mydata_file)

===============================

3.

merged_data <- left_join( mydata, gnomad, by = c( “AA_ref” = “aa_ref”,
“position” = “position_2”, “AA_var” = “aa_var” ) )

===============================

4. Classify mutation types

===============================

merged_data <- merged_data %>% mutate( var_type = case_when( AA_var ==
“SYN” ~ “SYN”, AA_var == “STOP” ~ “STOP”, AA_var == “DEL” ~ “DEL”, # DEL
# AA_ref AA_var ， DEL Missense () is.na(AA_ref) | is.na(AA_var) ~
“DEL”, # ， Missense TRUE ~ “Missense” ) )

===============================

5. ( + Cell )

cell_colors <- c( “STOP” = “red”, # “DEL” = “#005496”, # “SYN” =
“#bdc3d2”, # “Missense” = “#9cc37b” # )

fc_cols <- c(“FC_PR8GFP_neg_pos”, “FC_WSNGFP_neg_pos”,
“FC_H7N9GFP_neg_pos”) plot_list <- list()

for(i in 1:length(fc_cols)){ fc_col_name <- fc_cols[i]

# allele_frequency > 0 ， log plot_data <- merged_data %>%
filter(allele_frequency > 0) %>%

    # === ： ===
    # ： STOP  DEL ，，。
    # 1.  var_type  (Factor)
    # 2. ： Missense/SYN， DEL/STOP
    mutate(
      var_type = factor(var_type, levels = c("Missense", "SYN", "DEL",

“STOP”)) ) %>% # arrange(var_type)

p <- ggplot(plot_data, aes(x = allele_frequency, y =
.data[[fc_col_name]], color = var_type)) + geom_point(size = 2, alpha =
0.7, shape = 16) +

    # X  Log10 
    scale_x_log10(
      breaks = scales::trans_breaks("log10", function(x) 10^x),
      labels = scales::trans_format("log10", scales::math_format(10^.x))
    ) +

    # ===  ===
    # ：scale_color_manual  values

， scale_color_manual(values = cell_colors, name = “Mutation Type”) +

    # 
    labs(title = paste("allele_frequency vs", fc_col_name),
         x = expression("allele_frequency (log"[10]~"scale)"),
         y = paste("Fold Change (FC)", fc_col_name)) +

    # === ： ===
    theme_minimal() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold"),
      # 
      axis.title.x = element_text(face = "bold"),
      axis.title.y = element_text(face = "bold"),
      # 
      axis.text.x = element_text(size = 10, face = "bold"),
      axis.text.y = element_text(face = "bold"),
      # 
      legend.title = element_text(face = "bold"),
      # 
      legend.text = element_text(face = "bold")
    )

# plot_list[[i]] <- p }

combined_plot <- grid.arrange(grobs = plot_list, ncol = 2)
print(combined_plot)

Highlight validated variants，， lof 。。

Load required packages

library(dplyr) library(readr) library(readxl) library(ggplot2)
library(tidyr) library(gridExtra) library(ggrepel) #

===============================

1. gnomAD

===============================

gnomad <- read_csv(

“/Users/.../gnomAD_
v4.1.0_IFITM3_filtered_parsed.csv”, show_col_types = FALSE ) %>%
clean_names()

===============================

2.

===============================

mydata_file <-
“/Users/chenjian9007163.com/Desktop/bk/IFITM3library/3virus_analysis/merged_
A549.xlsx” mydata <- read_excel(mydata_file)

===============================

3.

===============================

merged_data <- left_join( mydata, gnomad, by = c( “AA_ref” = “aa_ref”,
“position” = “position_2”, “AA_var” = “aa_var” ) )

===============================

4. Classify mutation types

===============================

merged_data <- merged_data %>% mutate( var_type = case_when( AA_var ==
“SYN” ~ “SYN”, AA_var == “STOP” ~ “STOP”, AA_var == “DEL” ~ “DEL”,
is.na(AA_ref) | is.na(AA_var) ~ “DEL”, TRUE ~ “Missense” ) )

===============================

5. <<–

===============================

highlight_mutations <- tibble::tribble( ~AA_ref, ~position, ~AA_var,
“G”, 95, “R”, “D”, 86, “H”, “M”, 68, “T”, “R”, 85, “E”, “T”, 94, “DEL”,
“L”, 116, “R”, “K”, 104, “DEL”, “P”, 70, “R” )

， allele_frequency = 0

highlight_data <- merged_data %>% right_join(highlight_mutations, by =
c(“AA_ref”, “position”, “AA_var”)) %>% filter(allele_frequency > 0) %>%
# position_AA_var mutate(label = paste(position, AA_var, sep = “_“))

===============================

6.

===============================

cell_colors <- c( “STOP” = “red”, “DEL” = “#005496”, “SYN” = “#bdc3d2”,
# “Missense” = “#9cc37b” # )

fc_cols <- c(“FC_PR8GFP_neg_pos”, “FC_WSNGFP_neg_pos”,
“FC_H7N9GFP_neg_pos”) plot_list <- list()

for(i in 1:length(fc_cols)){ fc_col_name <- fc_cols[i]

# 1. () plot_data <- merged_data %>% filter(allele_frequency > 0) %>%
mutate( var_type = factor(var_type, levels = c(“Missense”, “SYN”, “DEL”,
“STOP”)) ) %>% arrange(var_type)

# 2. ( FC ) current_highlight_data <- highlight_data %>%
select(allele_frequency, var_type, label, !!fc_col_name)

p <- ggplot(plot_data, aes(x = allele_frequency, y =
.data[[fc_col_name]], color = var_type)) +

    #  ()
    geom_point(size = 3, alpha = 0.7, shape = 16) +

    # ===  ===
    geom_point(data = current_highlight_data,
               aes(x = allele_frequency, y = .data[[fc_col_name]]),
               color = "black", fill = "black", size = 3, shape = 16, alpha

= 1, inherit.aes = FALSE) +

    # ===  ( ggrepel ) ===
    geom_text_repel(data = current_highlight_data,
                    aes(x = allele_frequency, y = .data[[fc_col_name]],

label = label), color = “black”, size = 4, box.padding = 0.5,
point.padding = 0.5, segment.color = ‘grey50’, min.segment.length = 0,
fontface = ‘bold’, inherit.aes = FALSE) +

    # X  Log10 
    scale_x_log10(
      breaks = scales::trans_breaks("log10", function(x) 10^x),
      labels = scales::trans_format("log10", scales::math_format(10^.x))
    ) +

    # 
    scale_color_manual(values = cell_colors, name = "Mutation Type") +

    # 
    labs(title = paste("allele_frequency vs", fc_col_name),
         x = expression("allele_frequency (log"[10]~"scale)"),
         y = paste(fc_col_name)) +

    # 
    theme_minimal() +
    theme(
      plot.title = element_text(hjust = 0.5, face = "bold"),
      axis.title.x = element_text(face = "bold", color = 'black'),
      axis.title.y = element_text(face = "bold", color = 'black'),
      axis.text.x = element_text(size = 12, face = "bold", color =

‘black’), axis.text.y = element_text(size = 12,face = “bold”, color =
‘black’), legend.title = element_text(face = “bold”), legend.text =
element_text(face = “bold”) )

# plot_list[[i]] <- p } ## Print output cat(“— Print output — ”)
print(plot_list[[1]]) # FC_PR8GFP_neg_pos print(plot_list[[2]]) #
FC_WSNGFP_neg_pos print(plot_list[[3]]) # FC_H7N9GFP_neg_pos

combined_plot <- grid.arrange(grobs = plot_list, ncol = 2)
print(combined_plot)

###。 evolutionary conservationfitness

library(readr) library(dplyr) library(ggplot2)

—- 1. Read data —-

df <- read_csv(

“/Users/.../conserv
ation_A549_fitness.csv” )

df <- df %>% filter(!is.na(position)) %>% mutate( position =
as.numeric(position), color_group = case_when( position %in% 58:68 ~ “AP
58–68”, position %in% c(71,72,105) ~ “Cys cluster”, position %in%
c(24,83,88,104) ~ “Lys cluster”, TRUE ~ “Background” ) )

dfcolor_(g)roup < −factor(dfcolor_group, levels = c(“AP 58–68”, “Cys
cluster”, “Lys cluster”, “Background”) )

—- 2. Color palette (CNS-style, muted but decisive) —-

color_map <- c( “AP 58–68” = “#C00000”, “Cys cluster” = “#3B9AB2”, “Lys
cluster” = “#E1AF00”, “Background” = “grey70” )

—- 3. Main plotting function (With Auto-Correlation Annotation) —-

plot_cns_main <- function(data, xvar, xlabel) {

# Spearman p cor_res <- cor.test(data[[xvar]],
data$conservation, method = "spearman",
use = "complete.obs")
  rho_val <- round(cor_res$estimate, 2) p_val <- cor_res$p.value

# p p_label <- if (p_val < 0.001) “p < 0.001” else paste0(“p =”,
round(p_val, 3)) stat_text <- paste0(“Spearman’s R =”, rho_val, “”,
p_label)

ggplot(data, aes(x = .data[[xvar]], y = conservation)) +

    # ---- Density background (structure awareness) ----

geom_density_2d_filled( data = subset(data, color_group ==
“Background”), contour_var = “ndensity”, alpha = 0.18, show.legend =
FALSE ) +

    # ---- Background points (down-weighted) ----

geom_point( data = subset(data, color_group == “Background”), color =
“grey65”, size = 2, alpha = 0.45 ) +

    # ---- Highlighted functional residues ----

geom_point( data = subset(data, color_group != “Background”), aes(color
= color_group), size = 3.4, alpha = 0.95 ) +

    # ---- Global trend (LOESS) ----

geom_smooth( aes(group = 1), method = “loess”, color = “black”,
linewidth = 0.9, se = TRUE, alpha = 0.12 ) +

    # 
    annotate(
      "text",
      x = -Inf, y = Inf,
      label = stat_text,
      hjust = -0.1, vjust = 1.2,
      fontface = "bold.italic",
      size = 4.5,
      color = "black"
    ) +

    scale_color_manual(
      values = color_map,
      name   = "Functional class"
    ) +

    labs(
      x = xlabel,
      y = "Evolutionary conservation",
      title = NULL
    ) +

    theme_classic(base_size = 15) +
    theme(
      plot.title      = element_text(hjust = 0.5, face = "bold"),
      axis.title      = element_text(face = "bold"),
      axis.text       = element_text(face = "bold"),
      legend.position = "none" # 【】 Legend
    )

}

—- 4. Generate plots —-

p_pr8 <- plot_cns_main(df, “FC_PR8GFP_neg_pos”, “PR8 fitness”) p_wsn <-
plot_cns_main(df, “FC_WSNGFP_neg_pos”, “WSN fitness”) p_h7n9 <-
plot_cns_main(df, “FC_H7N9GFP_neg_pos”, “H7N9 fitness”)

p_pr8 p_wsn p_h7n9

—- 5. Export figures with fixed size and 300 DPI —-

（： 6 ， 5 ，）

fig_width <- 6 fig_height <- 4 fig_units <- “in” # “in” ， “cm” fig_dpi
<- 300 # 300 DPI

PR8

ggsave( filename = “Figure3_Conservation_PR8_300dpi.png”, plot = p_pr8,
width = fig_width, height = fig_height, units = fig_units, dpi =
fig_dpi, type = “cairo” # cairo )

WSN

ggsave( filename = “Figure3_Conservation_WSN_300dpi.png”, plot = p_wsn,
width = fig_width, height = fig_height, units = fig_units, dpi =
fig_dpi, type = “cairo” )

H7N9

ggsave( filename = “Figure3_Conservation_H7N9_300dpi.png”, plot =
p_h7n9, width = fig_width, height = fig_height, units = fig_units, dpi =
fig_dpi, type = “cairo” )

==============================

#。 #### # = alpha miss correlation ，。

1.

===============================

library(readxl) library(readr) library(dplyr) library(ggplot2)
library(ggpubr)

===============================

2.

===============================

file1 <-
“/Users/.../merged_
A549.xlsx” file2 <-
“/Users/.../AlphaMi
ssense-IFITM3-Q01628.tsv”

===============================

3. Read data

===============================

data1 <- read_excel(file1)

data2 <- read_tsv(file2) %>% setNames(gsub(“#”, ““, names(.))) %>%
setNames(make.names(names(.)))

===============================

4.

===============================

merged_data <- inner_join( data2, data1, by = c( “a.a.1” = “AA_ref”,
“position” = “position”, “a.a.2” = “AA_var” ) )

===============================

5. CNS / Cell （）

===============================

create_density_cor_plot <- function(df, y_var, title, y_label, method =
“spearman”) {

df <- df %>% filter( !is.na(pathogenicity.score), !is.na(.data[[y_var]])
)

## cor_test <- cor.test( df$pathogenicity.score, df[[y_var]], method =
method )

r_val <- round(cor_testestimate, 2)p_(v)al < −formatC(cor_(t)estp.value,
format = “e”, digits = 2)

ggplot(df, aes(x = pathogenicity.score, y = .data[[y_var]])) +

    ## （）
    geom_point(
      size = 1.2,
      alpha = 0.28,
      color = "grey70"
    ) +

    ## （Cell ）
    stat_density_2d(
      aes(fill = after_stat(level)),
      geom = "polygon",
      contour = TRUE,
      contour_var = "count",
      alpha = 0.45
    ) +

    ## 
    stat_density_2d(
      contour = TRUE,
      contour_var = "count",
      colour = "black",
      linewidth = 0.6
    ) +

    ## 
    geom_smooth(
      method = "lm",
      se = FALSE,
      linetype = "dashed",
      color = "white",
      linewidth = 1
    ) +

    ## r / p 
    annotate(
      "text",
      x = 0.15,
      y = 0.1,
      hjust = 0,
      vjust = 0,
      label = paste0(
        "Spearman r = ", r_val, "\n",
        "p = ", p_val
      ),
      size = 4.2,
      fontface = "bold"
    ) +

    ## 
    scale_x_continuous(
      limits = c(0, 1.2),
      expand = c(0, 0)
    ) +
    scale_y_continuous(
      limits = c(0, 2),
      expand = c(0, 0)
    ) +

    ## Cell 
    scale_fill_gradient(
      low  = "#deebf7",
      high = "#3182bd"
    ) +

    labs(
      title = title,
      x = "AlphaMissense pathogenicity score",
      y = y_label
    ) +

    ##  ： + 
    theme_classic(base_size = 14) +
    theme(
      ## panel 
      panel.border = element_rect(
        color = "black",
        fill  = NA,
        linewidth = 0.8
      ),

      ## 
      axis.text = element_text(
        size = 13,
        face = "bold",
        color = "black"
      ),

      ## 
      axis.title = element_text(
        size = 16,
        face = "bold"
      ),

      ## panel 
      plot.title = element_text(
        hjust = 0.5,
        face = "bold",
        size = 15
      ),

      axis.ticks = element_line(linewidth = 0.8),
      legend.position = "none"
    )

}

===============================

6. Figure 4D–F

===============================

plot_PR8 <- create_density_cor_plot( merged_data, “FC_PR8GFP_neg_pos”,
“PR8”, “FC (PR8 NP− / NP+)” )

plot_WSN <- create_density_cor_plot( merged_data, “FC_WSNGFP_neg_pos”,
“WSN”, “FC (WSN NP− / NP+)” )

plot_H7N9 <- create_density_cor_plot( merged_data, “FC_H7N9GFP_neg_pos”,
“H7N9”, “FC (H7N9 NP− / NP+)” )

===============================

7.

===============================

print(plot_PR8) print(plot_WSN) print(plot_H7N9)

===============================

8.（） Figure 4D–F

===============================

ggarrange( plot_PR8, plot_WSN, plot_H7N9, ncol = 3, labels = c(“D”, “E”,
“F”) )

===============================

8.（） Figure 4D–F

===============================

ggarrange( plot_PR8, plot_WSN, plot_H7N9, ncol = 3 )

[1] A-Za-z

[2] A-Za-z

[3] A-Za-z
