library(readxl); library(dplyr); library(tidyr); library(ggplot2); library(knitr); library(kableExtra); library(scales)
theme_report <- function() { theme_minimal(base_size=12) + theme(plot.title=element_text(face="bold",size=14,hjust=0,color="#1a365d"), plot.subtitle=element_text(size=11,hjust=0,color="#4a5568"), legend.position="bottom", panel.grid.minor=element_blank(), axis.title=element_text(face="bold",size=11), strip.text=element_text(face="bold",size=11)) }
theme_set(theme_report())setwd("C:/Users/SAlemu/OneDrive - CGIAR/Documents/Poultryaudit/Dataset/")
file_path <- "Additional_Poultry dataset_audit.xlsx"
lil_data <- read_excel(file_path, sheet = "LIL")
bil_data <- read_excel(file_path, sheet = "BIL")
nhil_data <- read_excel(file_path, sheet = "NHIL")
clean_names <- function(df) { colnames(df) <- gsub(" ", "_", colnames(df)); return(df) }
lil_data <- clean_names(lil_data); bil_data <- clean_names(bil_data); nhil_data <- clean_names(nhil_data)
convert_types <- function(df) { df$Generation <- as.character(df$Generation); df$Batch <- as.character(df$Batch); df$ID <- as.character(df$ID); df$Sire_ID <- as.character(df$Sire_ID); df$Dam_ID <- as.character(df$Dam_ID); return(df) }
lil_data <- convert_types(lil_data); bil_data <- convert_types(bil_data); nhil_data <- convert_types(nhil_data)
total_birds <- nrow(lil_data) + nrow(bil_data) + nrow(nhil_data)
lil_total <- nrow(lil_data); bil_total <- nrow(bil_data); nhil_total <- nrow(nhil_data)
lil_bw16_mean <- round(mean(lil_data$BW_16wk, na.rm=T), 0)
bil_bw16_mean <- round(mean(bil_data$BW_16wk, na.rm=T), 0)
nhil_bw16_mean <- round(mean(nhil_data$BW_16wk, na.rm=T), 0)
lil_survival <- round((1-sum(!is.na(lil_data$Cull_Reason))/lil_total)*100, 1)
bil_survival <- round((1-sum(!is.na(bil_data$Cull_Reason))/bil_total)*100, 1)
nhil_survival <- round((1-sum(!is.na(nhil_data$Cull_Reason))/nhil_total)*100, 1)
afe_col <- which(grepl("AFE", colnames(lil_data)))[1]
lil_egg_n <- sum(!is.na(lil_data[[afe_col]]))
bil_egg_n <- sum(!is.na(bil_data[[afe_col]]))
nhil_egg_n <- sum(!is.na(nhil_data[[afe_col]]))This report presents descriptive statistics for three ILRI poultry lines: LIL-20, BIL-20, and NHIL-20.
G0 founders have unknown parents by design — this is standard for base/foundation populations. Pedigree completeness for G1 and G2 determines suitability for genetic evaluation.
lil_gen <- lil_data %>% group_by(Generation) %>% summarise(N=n(), Males=sum(Sex=="M",na.rm=T), Females=sum(Sex=="F",na.rm=T), Unknown_Sex=sum(is.na(Sex)|Sex==""), Deaths=sum(!is.na(Cull_Reason)&Cull_Reason!=""), .groups="drop") %>% mutate(Survival_Pct=round((N-Deaths)/N*100,1), Generation=paste0("G",Generation))
lil_gen %>% kable(col.names=c("Gen","Total","Males","Females","Unknown","Deaths","Survival %")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=T) %>% row_spec(0,bold=T,background="#3182ce",color="white")| Gen | Total | Males | Females | Unknown | Deaths | Survival % |
|---|---|---|---|---|---|---|
| G0 | 612 | 122 | 175 | 315 | 292 | 52.3 |
| G1 | 157 | 58 | 76 | 23 | 15 | 90.4 |
| G2 | 446 | 219 | 222 | 5 | 0 | 100.0 |
lil_data %>% group_by(Generation,Batch) %>% summarise(N=n(),.groups="drop") %>% mutate(Generation=paste0("G",Generation)) %>% kable(col.names=c("Gen","Batch","N")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#3182ce",color="white")| Gen | Batch | N |
|---|---|---|
| G0 | 1 | 219 |
| G0 | 2 | 149 |
| G0 | 3 | 244 |
| G1 | 1 | 54 |
| G1 | 2 | 70 |
| G1 | 3 | 33 |
| G2 | 1 | 265 |
| G2 | 2 | 181 |
lil_ped <- lil_data %>% group_by(Generation) %>% summarise(N=n(), Sire_Known=sum(!is.na(Sire_ID)&Sire_ID!=""&Sire_ID!="NA"), Dam_Known=sum(!is.na(Dam_ID)&Dam_ID!=""&Dam_ID!="NA"), Unique_Sires=n_distinct(Sire_ID[!is.na(Sire_ID)&Sire_ID!=""&Sire_ID!="NA"]), Unique_Dams=n_distinct(Dam_ID[!is.na(Dam_ID)&Dam_ID!=""&Dam_ID!="NA"]), .groups="drop") %>% mutate(Sire_Pct=round(Sire_Known/N*100,1), Dam_Pct=round(Dam_Known/N*100,1), Offspring_per_Sire=ifelse(Unique_Sires>0,round(Sire_Known/Unique_Sires,1),NA), Offspring_per_Dam=ifelse(Unique_Dams>0,round(Dam_Known/Unique_Dams,1),NA), Generation=paste0("G",Generation))
lil_ped %>% select(Generation,N,Sire_Known,Dam_Known,Sire_Pct,Dam_Pct) %>% kable(col.names=c("Gen","N","Sire Known","Dam Known","Sire %","Dam %")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#3182ce",color="white")| Gen | N | Sire Known | Dam Known | Sire % | Dam % |
|---|---|---|---|---|---|
| G0 | 612 | 0 | 0 | 0 | 0 |
| G1 | 157 | 157 | 157 | 100 | 100 |
| G2 | 446 | 446 | 446 | 100 | 100 |
lil_m <- lil_ped %>% filter(Unique_Sires>0) %>% select(Generation,Unique_Sires,Unique_Dams,Offspring_per_Sire,Offspring_per_Dam)
if(nrow(lil_m)>0) { lil_m %>% kable(col.names=c("Gen","Unique Sires","Unique Dams","Offspring/Sire","Offspring/Dam")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#38a169",color="white") } else { cat("No mating data available.\n") }| Gen | Unique Sires | Unique Dams | Offspring/Sire | Offspring/Dam |
|---|---|---|---|---|
| G1 | 11 | 22 | 14.3 | 7.1 |
| G2 | 12 | 43 | 37.2 | 10.4 |
lil_data %>% group_by(Generation) %>% summarise(N=n(), BW_0wk=round(mean(BW_0wk,na.rm=T),1), BW_8wk=round(mean(BW_8wk,na.rm=T),1), BW_12wk=round(mean(BW_12wk,na.rm=T),1), BW_16wk=round(mean(BW_16wk,na.rm=T),1), .groups="drop") %>% mutate(Generation=paste0("G",Generation)) %>% kable(col.names=c("Gen","N","Hatch(g)","8wk(g)","12wk(g)","16wk(g)")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#3182ce",color="white")| Gen | N | Hatch(g) | 8wk(g) | 12wk(g) | 16wk(g) |
|---|---|---|---|---|---|
| G0 | 612 | 31.2 | 356.8 | 713.6 | 933.0 |
| G1 | 157 | 35.2 | 328.7 | 684.3 | 949.5 |
| G2 | 446 | 33.6 | 413.6 | 666.2 | 1031.4 |
lil_data %>% filter(Sex %in% c("M","F")) %>% group_by(Sex) %>% summarise(N=n(), BW_0wk=round(mean(BW_0wk,na.rm=T),1), BW_8wk=round(mean(BW_8wk,na.rm=T),1), BW_12wk=round(mean(BW_12wk,na.rm=T),1), BW_16wk=round(mean(BW_16wk,na.rm=T),1), .groups="drop") %>% mutate(Sex=ifelse(Sex=="M","Male","Female")) %>% kable(col.names=c("Sex","N","Hatch(g)","8wk(g)","12wk(g)","16wk(g)")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#2d3748",color="white")| Sex | N | Hatch(g) | 8wk(g) | 12wk(g) | 16wk(g) |
|---|---|---|---|---|---|
| Female | 473 | 32.9 | 356.9 | 653.2 | 866.1 |
| Male | 399 | 33.2 | 420.4 | 745.4 | 1125.4 |
lil_data %>% group_by(Generation) %>% summarise(BW_0wk=mean(BW_0wk,na.rm=T), BW_8wk=mean(BW_8wk,na.rm=T), BW_12wk=mean(BW_12wk,na.rm=T), BW_16wk=mean(BW_16wk,na.rm=T), .groups="drop") %>% pivot_longer(-Generation,names_to="Trait",values_to="Mean") %>% mutate(Generation=paste0("G",Generation), Trait=factor(Trait,levels=c("BW_0wk","BW_8wk","BW_12wk","BW_16wk"),labels=c("Hatch","8wk","12wk","16wk"))) %>% ggplot(aes(x=Generation,y=Mean,fill=Generation)) + geom_bar(stat="identity",width=0.6) + geom_text(aes(label=round(Mean,0)),vjust=-0.5,size=3.5) + facet_wrap(~Trait,scales="free_y") + scale_fill_manual(values=c("#3182ce","#38a169","#805ad5")) + labs(title="LIL-20: Mean Body Weight by Generation",x="Generation",y="Mean BW (g)") + theme(legend.position="none") + scale_y_continuous(expand=expansion(mult=c(0,0.15)))afe_col <- colnames(lil_data)[grepl("AFE",colnames(lil_data))][1]
lil_egg <- lil_data %>% filter(!is.na(.data[[afe_col]])|!is.na(Egg_no_45wk)|!is.na(Egg_weight))
cat("Birds with egg data:",nrow(lil_egg),"\n")## Birds with egg data: 48
if(nrow(lil_egg)>0) { data.frame(Trait=c("AFE(wk)","Egg_no_45wk","Egg_wt(g)"), N=c(sum(!is.na(lil_egg[[afe_col]])),sum(!is.na(lil_egg$Egg_no_45wk)),sum(!is.na(lil_egg$Egg_weight))), Mean=round(c(mean(lil_egg[[afe_col]],na.rm=T),mean(lil_egg$Egg_no_45wk,na.rm=T),mean(lil_egg$Egg_weight,na.rm=T)),2), SD=round(c(sd(lil_egg[[afe_col]],na.rm=T),sd(lil_egg$Egg_no_45wk,na.rm=T),sd(lil_egg$Egg_weight,na.rm=T)),2)) %>% kable(col.names=c("Trait","N","Mean","SD")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#3182ce",color="white") }| Trait | N | Mean | SD |
|---|---|---|---|
| AFE(wk) | 46 | 25.41 | 2.24 |
| Egg_no_45wk | 48 | 92.12 | 21.00 |
| Egg_wt(g) | 48 | 45.38 | 9.88 |
bil_gen <- bil_data %>% group_by(Generation) %>% summarise(N=n(), Males=sum(Sex=="M",na.rm=T), Females=sum(Sex=="F",na.rm=T), Unknown_Sex=sum(is.na(Sex)|Sex==""), Deaths=sum(!is.na(Cull_Reason)&Cull_Reason!=""), .groups="drop") %>% mutate(Survival_Pct=round((N-Deaths)/N*100,1), Generation=paste0("G",Generation))
bil_gen %>% kable(col.names=c("Gen","Total","Males","Females","Unknown","Deaths","Survival %")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=T) %>% row_spec(0,bold=T,background="#38a169",color="white")| Gen | Total | Males | Females | Unknown | Deaths | Survival % |
|---|---|---|---|---|---|---|
| G0 | 300 | 155 | 136 | 9 | 30 | 90.0 |
| G1 | 155 | 71 | 53 | 31 | 18 | 88.4 |
| G2 | 342 | 179 | 160 | 3 | 9 | 97.4 |
bil_data %>% group_by(Generation,Batch) %>% summarise(N=n(),.groups="drop") %>% mutate(Generation=paste0("G",Generation)) %>% kable(col.names=c("Gen","Batch","N")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#38a169",color="white")| Gen | Batch | N |
|---|---|---|
| G0 | 1 | 300 |
| G1 | 1 | 22 |
| G1 | 2 | 57 |
| G1 | 3 | 76 |
| G2 | 1 | 156 |
| G2 | 2 | 116 |
| G2 | 3 | 70 |
bil_ped <- bil_data %>% group_by(Generation) %>% summarise(N=n(), Sire_Known=sum(!is.na(Sire_ID)&Sire_ID!=""&Sire_ID!="NA"), Dam_Known=sum(!is.na(Dam_ID)&Dam_ID!=""&Dam_ID!="NA"), Unique_Sires=n_distinct(Sire_ID[!is.na(Sire_ID)&Sire_ID!=""&Sire_ID!="NA"]), Unique_Dams=n_distinct(Dam_ID[!is.na(Dam_ID)&Dam_ID!=""&Dam_ID!="NA"]), .groups="drop") %>% mutate(Sire_Pct=round(Sire_Known/N*100,1), Dam_Pct=round(Dam_Known/N*100,1), Offspring_per_Sire=ifelse(Unique_Sires>0,round(Sire_Known/Unique_Sires,1),NA), Offspring_per_Dam=ifelse(Unique_Dams>0,round(Dam_Known/Unique_Dams,1),NA), Generation=paste0("G",Generation))
bil_ped %>% select(Generation,N,Sire_Known,Dam_Known,Sire_Pct,Dam_Pct) %>% kable(col.names=c("Gen","N","Sire Known","Dam Known","Sire %","Dam %")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#38a169",color="white")| Gen | N | Sire Known | Dam Known | Sire % | Dam % |
|---|---|---|---|---|---|
| G0 | 300 | 0 | 0 | 0 | 0 |
| G1 | 155 | 155 | 155 | 100 | 100 |
| G2 | 342 | 342 | 342 | 100 | 100 |
bil_m <- bil_ped %>% filter(Unique_Sires>0) %>% select(Generation,Unique_Sires,Unique_Dams,Offspring_per_Sire,Offspring_per_Dam)
if(nrow(bil_m)>0) { bil_m %>% kable(col.names=c("Gen","Unique Sires","Unique Dams","Offspring/Sire","Offspring/Dam")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#38a169",color="white") } else { cat("No mating data available.\n") }| Gen | Unique Sires | Unique Dams | Offspring/Sire | Offspring/Dam |
|---|---|---|---|---|
| G1 | 6 | 27 | 25.8 | 5.7 |
| G2 | 8 | 39 | 42.8 | 8.8 |
bil_data %>% group_by(Generation) %>% summarise(N=n(), BW_0wk=round(mean(BW_0wk,na.rm=T),1), BW_8wk=round(mean(BW_8wk,na.rm=T),1), BW_12wk=round(mean(BW_12wk,na.rm=T),1), BW_16wk=round(mean(BW_16wk,na.rm=T),1), .groups="drop") %>% mutate(Generation=paste0("G",Generation)) %>% kable(col.names=c("Gen","N","Hatch(g)","8wk(g)","12wk(g)","16wk(g)")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#38a169",color="white")| Gen | N | Hatch(g) | 8wk(g) | 12wk(g) | 16wk(g) |
|---|---|---|---|---|---|
| G0 | 300 | NaN | 558.9 | 1022.8 | 1422.3 |
| G1 | 155 | 38.4 | 462.7 | 902.3 | 1345.9 |
| G2 | 342 | 36.2 | 522.7 | 853.9 | 1294.3 |
bil_data %>% filter(Sex %in% c("M","F")) %>% group_by(Sex) %>% summarise(N=n(), BW_0wk=round(mean(BW_0wk,na.rm=T),1), BW_8wk=round(mean(BW_8wk,na.rm=T),1), BW_12wk=round(mean(BW_12wk,na.rm=T),1), BW_16wk=round(mean(BW_16wk,na.rm=T),1), .groups="drop") %>% mutate(Sex=ifelse(Sex=="M","Male","Female")) %>% kable(col.names=c("Sex","N","Hatch(g)","8wk(g)","12wk(g)","16wk(g)")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#2d3748",color="white")| Sex | N | Hatch(g) | 8wk(g) | 12wk(g) | 16wk(g) |
|---|---|---|---|---|---|
| Female | 349 | 36.4 | 494.1 | 869.2 | 1200.1 |
| Male | 405 | 37.1 | 562.3 | 996.8 | 1494.2 |
bil_data %>% group_by(Generation) %>% summarise(BW_0wk=mean(BW_0wk,na.rm=T), BW_8wk=mean(BW_8wk,na.rm=T), BW_12wk=mean(BW_12wk,na.rm=T), BW_16wk=mean(BW_16wk,na.rm=T), .groups="drop") %>% pivot_longer(-Generation,names_to="Trait",values_to="Mean") %>% mutate(Generation=paste0("G",Generation), Trait=factor(Trait,levels=c("BW_0wk","BW_8wk","BW_12wk","BW_16wk"),labels=c("Hatch","8wk","12wk","16wk"))) %>% ggplot(aes(x=Generation,y=Mean,fill=Generation)) + geom_bar(stat="identity",width=0.6) + geom_text(aes(label=round(Mean,0)),vjust=-0.5,size=3.5) + facet_wrap(~Trait,scales="free_y") + scale_fill_manual(values=c("#38a169","#3182ce","#805ad5")) + labs(title="BIL-20: Mean Body Weight by Generation",x="Generation",y="Mean BW (g)") + theme(legend.position="none") + scale_y_continuous(expand=expansion(mult=c(0,0.15)))afe_col_bil <- colnames(bil_data)[grepl("AFE",colnames(bil_data))][1]
bil_egg <- bil_data %>% filter(!is.na(.data[[afe_col_bil]])|!is.na(Egg_no_45wk)|!is.na(Egg_weight))
cat("Birds with egg data:",nrow(bil_egg),"\n")## Birds with egg data: 43
if(nrow(bil_egg)>0) { data.frame(Trait=c("AFE(wk)","Egg_no_45wk","Egg_wt(g)"), N=c(sum(!is.na(bil_egg[[afe_col_bil]])),sum(!is.na(bil_egg$Egg_no_45wk)),sum(!is.na(bil_egg$Egg_weight))), Mean=round(c(mean(bil_egg[[afe_col_bil]],na.rm=T),mean(bil_egg$Egg_no_45wk,na.rm=T),mean(bil_egg$Egg_weight,na.rm=T)),2), SD=round(c(sd(bil_egg[[afe_col_bil]],na.rm=T),sd(bil_egg$Egg_no_45wk,na.rm=T),sd(bil_egg$Egg_weight,na.rm=T)),2)) %>% kable(col.names=c("Trait","N","Mean","SD")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#38a169",color="white") }| Trait | N | Mean | SD |
|---|---|---|---|
| AFE(wk) | 43 | 24.72 | 4.04 |
| Egg_no_45wk | 43 | 85.42 | 25.02 |
| Egg_wt(g) | 43 | 46.82 | 3.64 |
nhil_gen <- nhil_data %>% group_by(Generation) %>% summarise(N=n(), Males=sum(Sex=="M",na.rm=T), Females=sum(Sex=="F",na.rm=T), Unknown_Sex=sum(is.na(Sex)|Sex==""), Deaths=sum(!is.na(Cull_Reason)&Cull_Reason!=""), .groups="drop") %>% mutate(Survival_Pct=round((N-Deaths)/N*100,1), Generation=paste0("G",Generation))
nhil_gen %>% kable(col.names=c("Gen","Total","Males","Females","Unknown","Deaths","Survival %")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=T) %>% row_spec(0,bold=T,background="#805ad5",color="white")| Gen | Total | Males | Females | Unknown | Deaths | Survival % |
|---|---|---|---|---|---|---|
| G0 | 721 | 135 | 198 | 388 | 390 | 45.9 |
| G1 | 151 | 63 | 49 | 39 | 14 | 90.7 |
| G2 | 244 | 131 | 112 | 1 | 15 | 93.9 |
nhil_data %>% group_by(Generation,Batch) %>% summarise(N=n(),.groups="drop") %>% mutate(Generation=paste0("G",Generation)) %>% kable(col.names=c("Gen","Batch","N")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#805ad5",color="white")| Gen | Batch | N |
|---|---|---|
| G0 | 2 | 267 |
| G0 | 3 | 107 |
| G0 | 4 | 226 |
| G0 | 5 | 121 |
| G1 | 1 | 71 |
| G1 | 2 | 80 |
| G2 | 1 | 119 |
| G2 | 2 | 82 |
| G2 | 3 | 43 |
nhil_ped <- nhil_data %>% group_by(Generation) %>% summarise(N=n(), Sire_Known=sum(!is.na(Sire_ID)&Sire_ID!=""&Sire_ID!="NA"), Dam_Known=sum(!is.na(Dam_ID)&Dam_ID!=""&Dam_ID!="NA"), Unique_Sires=n_distinct(Sire_ID[!is.na(Sire_ID)&Sire_ID!=""&Sire_ID!="NA"]), Unique_Dams=n_distinct(Dam_ID[!is.na(Dam_ID)&Dam_ID!=""&Dam_ID!="NA"]), .groups="drop") %>% mutate(Sire_Pct=round(Sire_Known/N*100,1), Dam_Pct=round(Dam_Known/N*100,1), Offspring_per_Sire=ifelse(Unique_Sires>0,round(Sire_Known/Unique_Sires,1),NA), Offspring_per_Dam=ifelse(Unique_Dams>0,round(Dam_Known/Unique_Dams,1),NA), Generation=paste0("G",Generation))
nhil_ped %>% select(Generation,N,Sire_Known,Dam_Known,Sire_Pct,Dam_Pct) %>% kable(col.names=c("Gen","N","Sire Known","Dam Known","Sire %","Dam %")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#805ad5",color="white")| Gen | N | Sire Known | Dam Known | Sire % | Dam % |
|---|---|---|---|---|---|
| G0 | 721 | 0 | 0 | 0 | 0 |
| G1 | 151 | 151 | 151 | 100 | 100 |
| G2 | 244 | 244 | 244 | 100 | 100 |
nhil_m <- nhil_ped %>% filter(Unique_Sires>0) %>% select(Generation,Unique_Sires,Unique_Dams,Offspring_per_Sire,Offspring_per_Dam)
if(nrow(nhil_m)>0) { nhil_m %>% kable(col.names=c("Gen","Unique Sires","Unique Dams","Offspring/Sire","Offspring/Dam")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#805ad5",color="white") } else { cat("No mating data available.\n") }| Gen | Unique Sires | Unique Dams | Offspring/Sire | Offspring/Dam |
|---|---|---|---|---|
| G1 | 5 | 24 | 30.2 | 6.3 |
| G2 | 6 | 27 | 40.7 | 9.0 |
nhil_data %>% group_by(Generation) %>% summarise(N=n(), BW_0wk=round(mean(BW_0wk,na.rm=T),1), BW_8wk=round(mean(BW_8wk,na.rm=T),1), BW_12wk=round(mean(BW_12wk,na.rm=T),1), BW_16wk=round(mean(BW_16wk,na.rm=T),1), .groups="drop") %>% mutate(Generation=paste0("G",Generation)) %>% kable(col.names=c("Gen","N","Hatch(g)","8wk(g)","12wk(g)","16wk(g)")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#805ad5",color="white")| Gen | N | Hatch(g) | 8wk(g) | 12wk(g) | 16wk(g) |
|---|---|---|---|---|---|
| G0 | 721 | 40.8 | 414.5 | 707.3 | 1062.1 |
| G1 | 151 | 39.7 | 467.7 | 804.2 | 1170.6 |
| G2 | 244 | 40.2 | 578.9 | 966.5 | 1414.8 |
nhil_data %>% filter(Sex %in% c("M","F")) %>% group_by(Sex) %>% summarise(N=n(), BW_0wk=round(mean(BW_0wk,na.rm=T),1), BW_8wk=round(mean(BW_8wk,na.rm=T),1), BW_12wk=round(mean(BW_12wk,na.rm=T),1), BW_16wk=round(mean(BW_16wk,na.rm=T),1), .groups="drop") %>% mutate(Sex=ifelse(Sex=="M","Male","Female")) %>% kable(col.names=c("Sex","N","Hatch(g)","8wk(g)","12wk(g)","16wk(g)")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#2d3748",color="white")| Sex | N | Hatch(g) | 8wk(g) | 12wk(g) | 16wk(g) |
|---|---|---|---|---|---|
| Female | 359 | 40.3 | 436.9 | 733.5 | 995.0 |
| Male | 329 | 40.6 | 551.4 | 972.9 | 1427.1 |
nhil_data %>% group_by(Generation) %>% summarise(BW_0wk=mean(BW_0wk,na.rm=T), BW_8wk=mean(BW_8wk,na.rm=T), BW_12wk=mean(BW_12wk,na.rm=T), BW_16wk=mean(BW_16wk,na.rm=T), .groups="drop") %>% pivot_longer(-Generation,names_to="Trait",values_to="Mean") %>% mutate(Generation=paste0("G",Generation), Trait=factor(Trait,levels=c("BW_0wk","BW_8wk","BW_12wk","BW_16wk"),labels=c("Hatch","8wk","12wk","16wk"))) %>% ggplot(aes(x=Generation,y=Mean,fill=Generation)) + geom_bar(stat="identity",width=0.6) + geom_text(aes(label=round(Mean,0)),vjust=-0.5,size=3.5) + facet_wrap(~Trait,scales="free_y") + scale_fill_manual(values=c("#805ad5","#3182ce","#38a169")) + labs(title="NHIL-20: Mean Body Weight by Generation",x="Generation",y="Mean BW (g)") + theme(legend.position="none") + scale_y_continuous(expand=expansion(mult=c(0,0.15)))afe_col_nhil <- colnames(nhil_data)[grepl("AFE",colnames(nhil_data))][1]
nhil_egg <- nhil_data %>% filter(!is.na(.data[[afe_col_nhil]])|!is.na(Egg_no_45wk)|!is.na(Egg_weight))
cat("Birds with egg data:",nrow(nhil_egg),"\n")## Birds with egg data: 31
if(nrow(nhil_egg)>0) { data.frame(Trait=c("AFE(wk)","Egg_no_45wk","Egg_wt(g)"), N=c(sum(!is.na(nhil_egg[[afe_col_nhil]])),sum(!is.na(nhil_egg$Egg_no_45wk)),sum(!is.na(nhil_egg$Egg_weight))), Mean=round(c(mean(nhil_egg[[afe_col_nhil]],na.rm=T),mean(nhil_egg$Egg_no_45wk,na.rm=T),mean(nhil_egg$Egg_weight,na.rm=T)),2), SD=round(c(sd(nhil_egg[[afe_col_nhil]],na.rm=T),sd(nhil_egg$Egg_no_45wk,na.rm=T),sd(nhil_egg$Egg_weight,na.rm=T)),2)) %>% kable(col.names=c("Trait","N","Mean","SD")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#805ad5",color="white") }| Trait | N | Mean | SD |
|---|---|---|---|
| AFE(wk) | 31 | 24.90 | 2.39 |
| Egg_no_45wk | 31 | 71.26 | 15.29 |
| Egg_wt(g) | 0 | NaN | NA |
data.frame(Line=c("LIL-20","BIL-20","NHIL-20","TOTAL"), Total=c(lil_total,bil_total,nhil_total,total_birds), G0=c(sum(lil_data$Generation=="0"),sum(bil_data$Generation=="0"),sum(nhil_data$Generation=="0"),sum(lil_data$Generation=="0")+sum(bil_data$Generation=="0")+sum(nhil_data$Generation=="0")), G1=c(sum(lil_data$Generation=="1"),sum(bil_data$Generation=="1"),sum(nhil_data$Generation=="1"),sum(lil_data$Generation=="1")+sum(bil_data$Generation=="1")+sum(nhil_data$Generation=="1")), G2=c(sum(lil_data$Generation=="2"),sum(bil_data$Generation=="2"),sum(nhil_data$Generation=="2"),sum(lil_data$Generation=="2")+sum(bil_data$Generation=="2")+sum(nhil_data$Generation=="2"))) %>% kable(col.names=c("Line","Total","G0","G1","G2")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#2d3748",color="white") %>% row_spec(4,bold=T,background="#f7fafc")| Line | Total | G0 | G1 | G2 |
|---|---|---|---|---|
| LIL-20 | 1215 | 612 | 157 | 446 |
| BIL-20 | 797 | 300 | 155 | 342 |
| NHIL-20 | 1116 | 721 | 151 | 244 |
| TOTAL | 3128 | 1633 | 463 | 1032 |
data.frame(Line=c("LIL-20","BIL-20","NHIL-20"), N=c(sum(!is.na(lil_data$BW_16wk)),sum(!is.na(bil_data$BW_16wk)),sum(!is.na(nhil_data$BW_16wk))), Mean=round(c(mean(lil_data$BW_16wk,na.rm=T),mean(bil_data$BW_16wk,na.rm=T),mean(nhil_data$BW_16wk,na.rm=T)),1), SD=round(c(sd(lil_data$BW_16wk,na.rm=T),sd(bil_data$BW_16wk,na.rm=T),sd(nhil_data$BW_16wk,na.rm=T)),1)) %>% kable(col.names=c("Line","N","Mean(g)","SD")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#2d3748",color="white")| Line | N | Mean(g) | SD |
|---|---|---|---|
| LIL-20 | 793 | 980.8 | 224.0 |
| BIL-20 | 686 | 1353.8 | 280.6 |
| NHIL-20 | 641 | 1196.4 | 409.5 |
all_data <- bind_rows(lil_data %>% mutate(Line="LIL-20"), bil_data %>% mutate(Line="BIL-20"), nhil_data %>% mutate(Line="NHIL-20"))
ggplot(all_data %>% filter(!is.na(BW_16wk)), aes(x=Line,y=BW_16wk,fill=Line)) + geom_boxplot(alpha=0.8,outlier.shape=21) + scale_fill_manual(values=c("LIL-20"="#3182ce","BIL-20"="#38a169","NHIL-20"="#805ad5")) + labs(title="Body Weight at 16 Weeks - Comparison Across Lines",x="Line",y="Body Weight (g)") + theme(legend.position="none")mating_all <- bind_rows(lil_ped %>% filter(Unique_Sires>0) %>% mutate(Line="LIL-20"), bil_ped %>% filter(Unique_Sires>0) %>% mutate(Line="BIL-20"), nhil_ped %>% filter(Unique_Sires>0) %>% mutate(Line="NHIL-20")) %>% select(Line,Generation,N,Unique_Sires,Unique_Dams,Offspring_per_Sire,Offspring_per_Dam)
if(nrow(mating_all)>0) { mating_all %>% kable(col.names=c("Line","Gen","N","Sires","Dams","Offspring/Sire","Offspring/Dam")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#2d3748",color="white") } else { cat("No mating data available.\n") }| Line | Gen | N | Sires | Dams | Offspring/Sire | Offspring/Dam |
|---|---|---|---|---|---|---|
| LIL-20 | G1 | 157 | 11 | 22 | 14.3 | 7.1 |
| LIL-20 | G2 | 446 | 12 | 43 | 37.2 | 10.4 |
| BIL-20 | G1 | 155 | 6 | 27 | 25.8 | 5.7 |
| BIL-20 | G2 | 342 | 8 | 39 | 42.8 | 8.8 |
| NHIL-20 | G1 | 151 | 5 | 24 | 30.2 | 6.3 |
| NHIL-20 | G2 | 244 | 6 | 27 | 40.7 | 9.0 |
# Check if parent IDs in G1/G2 actually exist in previous generations
check_pedigree <- function(data, line_name) {
g0_ids <- data %>% filter(Generation == "0") %>% pull(ID)
g1_ids <- data %>% filter(Generation == "1") %>% pull(ID)
# G1 parents should be in G0
g1_sires <- data %>% filter(Generation == "1", !is.na(Sire_ID), Sire_ID != "", Sire_ID != "NA") %>% pull(Sire_ID)
g1_dams <- data %>% filter(Generation == "1", !is.na(Dam_ID), Dam_ID != "", Dam_ID != "NA") %>% pull(Dam_ID)
# G2 parents should be in G1
g2_sires <- data %>% filter(Generation == "2", !is.na(Sire_ID), Sire_ID != "", Sire_ID != "NA") %>% pull(Sire_ID)
g2_dams <- data %>% filter(Generation == "2", !is.na(Dam_ID), Dam_ID != "", Dam_ID != "NA") %>% pull(Dam_ID)
data.frame(
Line = line_name,
G1_Sires_in_G0 = ifelse(length(g1_sires) > 0, paste0(sum(g1_sires %in% g0_ids), "/", length(g1_sires)), "0/0"),
G1_Dams_in_G0 = ifelse(length(g1_dams) > 0, paste0(sum(g1_dams %in% g0_ids), "/", length(g1_dams)), "0/0"),
G2_Sires_in_G1 = ifelse(length(g2_sires) > 0, paste0(sum(g2_sires %in% g1_ids), "/", length(g2_sires)), "0/0"),
G2_Dams_in_G1 = ifelse(length(g2_dams) > 0, paste0(sum(g2_dams %in% g1_ids), "/", length(g2_dams)), "0/0")
)
}
ped_check <- bind_rows(
check_pedigree(lil_data, "LIL-20"),
check_pedigree(bil_data, "BIL-20"),
check_pedigree(nhil_data, "NHIL-20")
)
ped_check %>%
kable(col.names = c("Line", "G1 Sires in G0", "G1 Dams in G0", "G2 Sires in G1", "G2 Dams in G1")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#2d3748", color = "white")| Line | G1 Sires in G0 | G1 Dams in G0 | G2 Sires in G1 | G2 Dams in G1 |
|---|---|---|---|---|
| LIL-20 | 157/157 | 157/157 | 347/446 | 361/446 |
| BIL-20 | 155/155 | 155/155 | 342/342 | 342/342 |
| NHIL-20 | 151/151 | 151/151 | 244/244 | 244/244 |
The table shows how many recorded parent IDs can be found in the previous generation. For example, “45/45” means all 45 sire IDs were found; “40/45” means 5 sire IDs are missing from the previous generation’s records.
data.frame(Measure=c("Total birds","Mean BW 16wk","Egg records","G1/G2 Pedigree"), LIL=c(lil_total,paste0(lil_bw16_mean,"g"),lil_egg_n,"See integrity check"), BIL=c(bil_total,paste0(bil_bw16_mean,"g"),bil_egg_n,"See integrity check"), NHIL=c(nhil_total,paste0(nhil_bw16_mean,"g"),nhil_egg_n,"See integrity check")) %>% kable(col.names=c("Measure","LIL-20","BIL-20","NHIL-20")) %>% kable_styling(bootstrap_options=c("striped","hover"),full_width=F) %>% row_spec(0,bold=T,background="#3182ce",color="white")| Measure | LIL-20 | BIL-20 | NHIL-20 |
|---|---|---|---|
| Total birds | 1215 | 797 | 1116 |
| Mean BW 16wk | 981g | 1354g | 1196g |
| Egg records | 46 | 43 | 31 |
| G1/G2 Pedigree | See integrity check | See integrity check | See integrity check |