A pipeline for evaluating the RGB data from Sarah Kezar’s experiment This is a part of a series of experiments on Parthenium sp. from various locations.

RGB data loading

list.files()
##  [1] "20250120_SarahK__Batch 3_coding.csv"    
##  [2] "20250206_Batch03_Parthenium_RGB.Rmd"    
##  [3] "20250206_Batch03_Parthenium.Rmd"        
##  [4] "20250207_Batch03_Parthenium_PS2.nb.html"
##  [5] "20250207_Batch03_Parthenium_PS2.Rmd"    
##  [6] "Batch.03.DigitalBiomass.csv"            
##  [7] "Batch.03.GrowthRate.csv"                
##  [8] "Batch03.RGB_data_per_Population.pdf"    
##  [9] "consolidated_data.csv"                  
## [10] "Exp_10191_Data_Analysis.csv"            
## [11] "Exp_10191_Data_Analysis.TXT"
RGB <- read.csv("consolidated_data.csv")
RGB

Let’s keep only the measurements that we are most interested in

unique(RGB$measurement_name)
##   [1] "Rfid"                            "Side01_00_row1"                 
##   [3] "Side01_00_area"                  "Side01_00_height"               
##   [5] "Side01_00_width"                 "Side01_00_circularity"          
##   [7] "Side01_00_compactness"           "Side01_00_contlength"           
##   [9] "Side01_00_convexity"             "Side01_00_rectangularity"       
##  [11] "Side01_00_anisometry"            "Side01_00_bulkiness"            
##  [13] "Side01_00_struct_factor"         "Side01_00_outer_radius"         
##  [15] "Side01_00_inner_radius"          "Side01_00_dist_mean"            
##  [17] "Side01_00_dist_deviation"        "Side01_00_roundness"            
##  [19] "Side01_00_holes_num"             "Side01_00_areaInMm2"            
##  [21] "Side01_00_heightInMm"            "Side01_00_widthInMm"            
##  [23] "Side01_00_Convex_Hull_Area"      "Side01_00_AverageColor_H"       
##  [25] "Side01_00_AverageColor_S"        "Side01_00_AverageColor_V"       
##  [27] "Side01_00_CenterOfMassX"         "Side01_00_CenterOfMassY"        
##  [29] "Side01_00_CenterOfMassDistance"  "Side01_00_H_Mean"               
##  [31] "Side01_00_H_Median"              "Side01_00_H_StDev"              
##  [33] "Side01_00_H_Q1"                  "Side01_00_H_Q3"                 
##  [35] "Side01_00_brown(H_14_27)"        "Side01_00_brown-yellow(H_28_35)"
##  [37] "Side01_00_yellow(H_36_43)"       "Side01_00_yellow-green(H_44_57)"
##  [39] "Side01_00_green(H_58_99)"        "Side01_00_green-cyan(H_100_120)"
##  [41] "Side01_00_cyan-blue(H_121_142)"  "Side01_00_blue(H_143_156)"      
##  [43] "Side01_00_HistoH_0_5"            "Side01_00_HistoH_5_10"          
##  [45] "Side01_00_HistoH_10_15"          "Side01_00_HistoH_15_20"         
##  [47] "Side01_00_HistoH_20_25"          "Side01_00_HistoH_25_30"         
##  [49] "Side01_00_HistoH_30_35"          "Side01_00_HistoH_35_40"         
##  [51] "Side01_00_HistoH_40_45"          "Side01_00_HistoH_45_50"         
##  [53] "Side01_00_HistoH_50_55"          "Side01_00_HistoH_55_60"         
##  [55] "Side01_00_HistoH_60_65"          "Side01_00_HistoH_65_70"         
##  [57] "Side01_00_HistoH_70_75"          "Side01_00_HistoH_75_80"         
##  [59] "Side01_00_HistoH_80_85"          "Side01_00_HistoH_85_90"         
##  [61] "Side01_00_HistoH_90_95"          "Side01_00_HistoH_95_100"        
##  [63] "Side01_00_HistoH_100_105"        "Side01_00_HistoH_105_110"       
##  [65] "Side01_00_HistoH_110_115"        "Side01_00_HistoH_115_120"       
##  [67] "Side01_00_HistoH_120_125"        "Side01_00_HistoH_125_130"       
##  [69] "Side01_00_HistoH_130_135"        "Side01_00_HistoH_135_140"       
##  [71] "Side01_00_HistoH_140_145"        "Side01_00_HistoH_145_150"       
##  [73] "Side01_00_HistoH_150_155"        "Side01_00_HistoH_155_160"       
##  [75] "Side01_00_HistoH_160_165"        "Side01_00_HistoH_165_170"       
##  [77] "Side01_00_HistoH_170_175"        "Side01_00_HistoH_175_180"       
##  [79] "Side01_00_HistoH_180_185"        "Side01_00_HistoH_185_190"       
##  [81] "Side01_00_HistoH_190_195"        "Side01_00_HistoH_195_200"       
##  [83] "Side01_00_HistoH_200_205"        "Side01_00_HistoH_205_210"       
##  [85] "Side01_00_HistoH_210_215"        "Side01_00_HistoH_215_220"       
##  [87] "Side01_00_HistoH_220_225"        "Side01_00_HistoH_225_230"       
##  [89] "Side01_00_HistoH_230_235"        "Side01_00_HistoH_235_240"       
##  [91] "Side01_00_HistoH_240_245"        "Side01_00_HistoH_245_250"       
##  [93] "Side01_00_HistoH_250_255"        "Side01_00_Greennes_Mean"        
##  [95] "Side01_00_Greennes_Deviation"    "Side01_00_BarcodeEnabled"       
##  [97] "Side01_00_BarcodeFound"          "BarcodeResult"                  
##  [99] "Side01_01_row1"                  "Side01_01_area"                 
## [101] "Side01_01_height"                "Side01_01_width"                
## [103] "Side01_01_circularity"           "Side01_01_compactness"          
## [105] "Side01_01_contlength"            "Side01_01_convexity"            
## [107] "Side01_01_rectangularity"        "Side01_01_anisometry"           
## [109] "Side01_01_bulkiness"             "Side01_01_struct_factor"        
## [111] "Side01_01_outer_radius"          "Side01_01_inner_radius"         
## [113] "Side01_01_dist_mean"             "Side01_01_dist_deviation"       
## [115] "Side01_01_roundness"             "Side01_01_holes_num"            
## [117] "Side01_01_areaInMm2"             "Side01_01_heightInMm"           
## [119] "Side01_01_widthInMm"             "Side01_01_Convex_Hull_Area"     
## [121] "Side01_01_AverageColor_H"        "Side01_01_AverageColor_S"       
## [123] "Side01_01_AverageColor_V"        "Side01_01_CenterOfMassX"        
## [125] "Side01_01_CenterOfMassY"         "Side01_01_CenterOfMassDistance" 
## [127] "Side01_01_H_Mean"                "Side01_01_H_Median"             
## [129] "Side01_01_H_StDev"               "Side01_01_H_Q1"                 
## [131] "Side01_01_H_Q3"                  "Side01_01_brown(H_14_27)"       
## [133] "Side01_01_brown-yellow(H_28_35)" "Side01_01_yellow(H_36_43)"      
## [135] "Side01_01_yellow-green(H_44_57)" "Side01_01_green(H_58_99)"       
## [137] "Side01_01_green-cyan(H_100_120)" "Side01_01_cyan-blue(H_121_142)" 
## [139] "Side01_01_blue(H_143_156)"       "Side01_01_HistoH_0_5"           
## [141] "Side01_01_HistoH_5_10"           "Side01_01_HistoH_10_15"         
## [143] "Side01_01_HistoH_15_20"          "Side01_01_HistoH_20_25"         
## [145] "Side01_01_HistoH_25_30"          "Side01_01_HistoH_30_35"         
## [147] "Side01_01_HistoH_35_40"          "Side01_01_HistoH_40_45"         
## [149] "Side01_01_HistoH_45_50"          "Side01_01_HistoH_50_55"         
## [151] "Side01_01_HistoH_55_60"          "Side01_01_HistoH_60_65"         
## [153] "Side01_01_HistoH_65_70"          "Side01_01_HistoH_70_75"         
## [155] "Side01_01_HistoH_75_80"          "Side01_01_HistoH_80_85"         
## [157] "Side01_01_HistoH_85_90"          "Side01_01_HistoH_90_95"         
## [159] "Side01_01_HistoH_95_100"         "Side01_01_HistoH_100_105"       
## [161] "Side01_01_HistoH_105_110"        "Side01_01_HistoH_110_115"       
## [163] "Side01_01_HistoH_115_120"        "Side01_01_HistoH_120_125"       
## [165] "Side01_01_HistoH_125_130"        "Side01_01_HistoH_130_135"       
## [167] "Side01_01_HistoH_135_140"        "Side01_01_HistoH_140_145"       
## [169] "Side01_01_HistoH_145_150"        "Side01_01_HistoH_150_155"       
## [171] "Side01_01_HistoH_155_160"        "Side01_01_HistoH_160_165"       
## [173] "Side01_01_HistoH_165_170"        "Side01_01_HistoH_170_175"       
## [175] "Side01_01_HistoH_175_180"        "Side01_01_HistoH_180_185"       
## [177] "Side01_01_HistoH_185_190"        "Side01_01_HistoH_190_195"       
## [179] "Side01_01_HistoH_195_200"        "Side01_01_HistoH_200_205"       
## [181] "Side01_01_HistoH_205_210"        "Side01_01_HistoH_210_215"       
## [183] "Side01_01_HistoH_215_220"        "Side01_01_HistoH_220_225"       
## [185] "Side01_01_HistoH_225_230"        "Side01_01_HistoH_230_235"       
## [187] "Side01_01_HistoH_235_240"        "Side01_01_HistoH_240_245"       
## [189] "Side01_01_HistoH_245_250"        "Side01_01_HistoH_250_255"       
## [191] "Side01_01_Greennes_Mean"         "Side01_01_Greennes_Deviation"   
## [193] "Side01_01_BarcodeEnabled"        "Side01_01_BarcodeFound"         
## [195] "Side01_02_row1"                  "Side01_02_area"                 
## [197] "Side01_02_height"                "Side01_02_width"                
## [199] "Side01_02_circularity"           "Side01_02_compactness"          
## [201] "Side01_02_contlength"            "Side01_02_convexity"            
## [203] "Side01_02_rectangularity"        "Side01_02_anisometry"           
## [205] "Side01_02_bulkiness"             "Side01_02_struct_factor"        
## [207] "Side01_02_outer_radius"          "Side01_02_inner_radius"         
## [209] "Side01_02_dist_mean"             "Side01_02_dist_deviation"       
## [211] "Side01_02_roundness"             "Side01_02_holes_num"            
## [213] "Side01_02_areaInMm2"             "Side01_02_heightInMm"           
## [215] "Side01_02_widthInMm"             "Side01_02_Convex_Hull_Area"     
## [217] "Side01_02_AverageColor_H"        "Side01_02_AverageColor_S"       
## [219] "Side01_02_AverageColor_V"        "Side01_02_CenterOfMassX"        
## [221] "Side01_02_CenterOfMassY"         "Side01_02_CenterOfMassDistance" 
## [223] "Side01_02_H_Mean"                "Side01_02_H_Median"             
## [225] "Side01_02_H_StDev"               "Side01_02_H_Q1"                 
## [227] "Side01_02_H_Q3"                  "Side01_02_brown(H_14_27)"       
## [229] "Side01_02_brown-yellow(H_28_35)" "Side01_02_yellow(H_36_43)"      
## [231] "Side01_02_yellow-green(H_44_57)" "Side01_02_green(H_58_99)"       
## [233] "Side01_02_green-cyan(H_100_120)" "Side01_02_cyan-blue(H_121_142)" 
## [235] "Side01_02_blue(H_143_156)"       "Side01_02_HistoH_0_5"           
## [237] "Side01_02_HistoH_5_10"           "Side01_02_HistoH_10_15"         
## [239] "Side01_02_HistoH_15_20"          "Side01_02_HistoH_20_25"         
## [241] "Side01_02_HistoH_25_30"          "Side01_02_HistoH_30_35"         
## [243] "Side01_02_HistoH_35_40"          "Side01_02_HistoH_40_45"         
## [245] "Side01_02_HistoH_45_50"          "Side01_02_HistoH_50_55"         
## [247] "Side01_02_HistoH_55_60"          "Side01_02_HistoH_60_65"         
## [249] "Side01_02_HistoH_65_70"          "Side01_02_HistoH_70_75"         
## [251] "Side01_02_HistoH_75_80"          "Side01_02_HistoH_80_85"         
## [253] "Side01_02_HistoH_85_90"          "Side01_02_HistoH_90_95"         
## [255] "Side01_02_HistoH_95_100"         "Side01_02_HistoH_100_105"       
## [257] "Side01_02_HistoH_105_110"        "Side01_02_HistoH_110_115"       
## [259] "Side01_02_HistoH_115_120"        "Side01_02_HistoH_120_125"       
## [261] "Side01_02_HistoH_125_130"        "Side01_02_HistoH_130_135"       
## [263] "Side01_02_HistoH_135_140"        "Side01_02_HistoH_140_145"       
## [265] "Side01_02_HistoH_145_150"        "Side01_02_HistoH_150_155"       
## [267] "Side01_02_HistoH_155_160"        "Side01_02_HistoH_160_165"       
## [269] "Side01_02_HistoH_165_170"        "Side01_02_HistoH_170_175"       
## [271] "Side01_02_HistoH_175_180"        "Side01_02_HistoH_180_185"       
## [273] "Side01_02_HistoH_185_190"        "Side01_02_HistoH_190_195"       
## [275] "Side01_02_HistoH_195_200"        "Side01_02_HistoH_200_205"       
## [277] "Side01_02_HistoH_205_210"        "Side01_02_HistoH_210_215"       
## [279] "Side01_02_HistoH_215_220"        "Side01_02_HistoH_220_225"       
## [281] "Side01_02_HistoH_225_230"        "Side01_02_HistoH_230_235"       
## [283] "Side01_02_HistoH_235_240"        "Side01_02_HistoH_240_245"       
## [285] "Side01_02_HistoH_245_250"        "Side01_02_HistoH_250_255"       
## [287] "Side01_02_Greennes_Mean"         "Side01_02_Greennes_Deviation"   
## [289] "Side01_02_BarcodeEnabled"        "Side01_02_BarcodeFound"         
## [291] "Side01_03_row1"                  "Side01_03_area"                 
## [293] "Side01_03_height"                "Side01_03_width"                
## [295] "Side01_03_circularity"           "Side01_03_compactness"          
## [297] "Side01_03_contlength"            "Side01_03_convexity"            
## [299] "Side01_03_rectangularity"        "Side01_03_anisometry"           
## [301] "Side01_03_bulkiness"             "Side01_03_struct_factor"        
## [303] "Side01_03_outer_radius"          "Side01_03_inner_radius"         
## [305] "Side01_03_dist_mean"             "Side01_03_dist_deviation"       
## [307] "Side01_03_roundness"             "Side01_03_holes_num"            
## [309] "Side01_03_areaInMm2"             "Side01_03_heightInMm"           
## [311] "Side01_03_widthInMm"             "Side01_03_Convex_Hull_Area"     
## [313] "Side01_03_AverageColor_H"        "Side01_03_AverageColor_S"       
## [315] "Side01_03_AverageColor_V"        "Side01_03_CenterOfMassX"        
## [317] "Side01_03_CenterOfMassY"         "Side01_03_CenterOfMassDistance" 
## [319] "Side01_03_H_Mean"                "Side01_03_H_Median"             
## [321] "Side01_03_H_StDev"               "Side01_03_H_Q1"                 
## [323] "Side01_03_H_Q3"                  "Side01_03_brown(H_14_27)"       
## [325] "Side01_03_brown-yellow(H_28_35)" "Side01_03_yellow(H_36_43)"      
## [327] "Side01_03_yellow-green(H_44_57)" "Side01_03_green(H_58_99)"       
## [329] "Side01_03_green-cyan(H_100_120)" "Side01_03_cyan-blue(H_121_142)" 
## [331] "Side01_03_blue(H_143_156)"       "Side01_03_HistoH_0_5"           
## [333] "Side01_03_HistoH_5_10"           "Side01_03_HistoH_10_15"         
## [335] "Side01_03_HistoH_15_20"          "Side01_03_HistoH_20_25"         
## [337] "Side01_03_HistoH_25_30"          "Side01_03_HistoH_30_35"         
## [339] "Side01_03_HistoH_35_40"          "Side01_03_HistoH_40_45"         
## [341] "Side01_03_HistoH_45_50"          "Side01_03_HistoH_50_55"         
## [343] "Side01_03_HistoH_55_60"          "Side01_03_HistoH_60_65"         
## [345] "Side01_03_HistoH_65_70"          "Side01_03_HistoH_70_75"         
## [347] "Side01_03_HistoH_75_80"          "Side01_03_HistoH_80_85"         
## [349] "Side01_03_HistoH_85_90"          "Side01_03_HistoH_90_95"         
## [351] "Side01_03_HistoH_95_100"         "Side01_03_HistoH_100_105"       
## [353] "Side01_03_HistoH_105_110"        "Side01_03_HistoH_110_115"       
## [355] "Side01_03_HistoH_115_120"        "Side01_03_HistoH_120_125"       
## [357] "Side01_03_HistoH_125_130"        "Side01_03_HistoH_130_135"       
## [359] "Side01_03_HistoH_135_140"        "Side01_03_HistoH_140_145"       
## [361] "Side01_03_HistoH_145_150"        "Side01_03_HistoH_150_155"       
## [363] "Side01_03_HistoH_155_160"        "Side01_03_HistoH_160_165"       
## [365] "Side01_03_HistoH_165_170"        "Side01_03_HistoH_170_175"       
## [367] "Side01_03_HistoH_175_180"        "Side01_03_HistoH_180_185"       
## [369] "Side01_03_HistoH_185_190"        "Side01_03_HistoH_190_195"       
## [371] "Side01_03_HistoH_195_200"        "Side01_03_HistoH_200_205"       
## [373] "Side01_03_HistoH_205_210"        "Side01_03_HistoH_210_215"       
## [375] "Side01_03_HistoH_215_220"        "Side01_03_HistoH_220_225"       
## [377] "Side01_03_HistoH_225_230"        "Side01_03_HistoH_230_235"       
## [379] "Side01_03_HistoH_235_240"        "Side01_03_HistoH_240_245"       
## [381] "Side01_03_HistoH_245_250"        "Side01_03_HistoH_250_255"       
## [383] "Side01_03_Greennes_Mean"         "Side01_03_Greennes_Deviation"   
## [385] "Side01_03_BarcodeEnabled"        "Side01_03_BarcodeFound"         
## [387] "Side01_04_row1"                  "Side01_04_area"                 
## [389] "Side01_04_height"                "Side01_04_width"                
## [391] "Side01_04_circularity"           "Side01_04_compactness"          
## [393] "Side01_04_contlength"            "Side01_04_convexity"            
## [395] "Side01_04_rectangularity"        "Side01_04_anisometry"           
## [397] "Side01_04_bulkiness"             "Side01_04_struct_factor"        
## [399] "Side01_04_outer_radius"          "Side01_04_inner_radius"         
## [401] "Side01_04_dist_mean"             "Side01_04_dist_deviation"       
## [403] "Side01_04_roundness"             "Side01_04_holes_num"            
## [405] "Side01_04_areaInMm2"             "Side01_04_heightInMm"           
## [407] "Side01_04_widthInMm"             "Side01_04_Convex_Hull_Area"     
## [409] "Side01_04_AverageColor_H"        "Side01_04_AverageColor_S"       
## [411] "Side01_04_AverageColor_V"        "Side01_04_CenterOfMassX"        
## [413] "Side01_04_CenterOfMassY"         "Side01_04_CenterOfMassDistance" 
## [415] "Side01_04_H_Mean"                "Side01_04_H_Median"             
## [417] "Side01_04_H_StDev"               "Side01_04_H_Q1"                 
## [419] "Side01_04_H_Q3"                  "Side01_04_brown(H_14_27)"       
## [421] "Side01_04_brown-yellow(H_28_35)" "Side01_04_yellow(H_36_43)"      
## [423] "Side01_04_yellow-green(H_44_57)" "Side01_04_green(H_58_99)"       
## [425] "Side01_04_green-cyan(H_100_120)" "Side01_04_cyan-blue(H_121_142)" 
## [427] "Side01_04_blue(H_143_156)"       "Side01_04_HistoH_0_5"           
## [429] "Side01_04_HistoH_5_10"           "Side01_04_HistoH_10_15"         
## [431] "Side01_04_HistoH_15_20"          "Side01_04_HistoH_20_25"         
## [433] "Side01_04_HistoH_25_30"          "Side01_04_HistoH_30_35"         
## [435] "Side01_04_HistoH_35_40"          "Side01_04_HistoH_40_45"         
## [437] "Side01_04_HistoH_45_50"          "Side01_04_HistoH_50_55"         
## [439] "Side01_04_HistoH_55_60"          "Side01_04_HistoH_60_65"         
## [441] "Side01_04_HistoH_65_70"          "Side01_04_HistoH_70_75"         
## [443] "Side01_04_HistoH_75_80"          "Side01_04_HistoH_80_85"         
## [445] "Side01_04_HistoH_85_90"          "Side01_04_HistoH_90_95"         
## [447] "Side01_04_HistoH_95_100"         "Side01_04_HistoH_100_105"       
## [449] "Side01_04_HistoH_105_110"        "Side01_04_HistoH_110_115"       
## [451] "Side01_04_HistoH_115_120"        "Side01_04_HistoH_120_125"       
## [453] "Side01_04_HistoH_125_130"        "Side01_04_HistoH_130_135"       
## [455] "Side01_04_HistoH_135_140"        "Side01_04_HistoH_140_145"       
## [457] "Side01_04_HistoH_145_150"        "Side01_04_HistoH_150_155"       
## [459] "Side01_04_HistoH_155_160"        "Side01_04_HistoH_160_165"       
## [461] "Side01_04_HistoH_165_170"        "Side01_04_HistoH_170_175"       
## [463] "Side01_04_HistoH_175_180"        "Side01_04_HistoH_180_185"       
## [465] "Side01_04_HistoH_185_190"        "Side01_04_HistoH_190_195"       
## [467] "Side01_04_HistoH_195_200"        "Side01_04_HistoH_200_205"       
## [469] "Side01_04_HistoH_205_210"        "Side01_04_HistoH_210_215"       
## [471] "Side01_04_HistoH_215_220"        "Side01_04_HistoH_220_225"       
## [473] "Side01_04_HistoH_225_230"        "Side01_04_HistoH_230_235"       
## [475] "Side01_04_HistoH_235_240"        "Side01_04_HistoH_240_245"       
## [477] "Side01_04_HistoH_245_250"        "Side01_04_HistoH_250_255"       
## [479] "Side01_04_Greennes_Mean"         "Side01_04_Greennes_Deviation"   
## [481] "Side01_04_BarcodeEnabled"        "Side01_04_BarcodeFound"         
## [483] "Side01_05_row1"                  "Side01_05_area"                 
## [485] "Side01_05_height"                "Side01_05_width"                
## [487] "Side01_05_circularity"           "Side01_05_compactness"          
## [489] "Side01_05_contlength"            "Side01_05_convexity"            
## [491] "Side01_05_rectangularity"        "Side01_05_anisometry"           
## [493] "Side01_05_bulkiness"             "Side01_05_struct_factor"        
## [495] "Side01_05_outer_radius"          "Side01_05_inner_radius"         
## [497] "Side01_05_dist_mean"             "Side01_05_dist_deviation"       
## [499] "Side01_05_roundness"             "Side01_05_holes_num"            
## [501] "Side01_05_areaInMm2"             "Side01_05_heightInMm"           
## [503] "Side01_05_widthInMm"             "Side01_05_Convex_Hull_Area"     
## [505] "Side01_05_AverageColor_H"        "Side01_05_AverageColor_S"       
## [507] "Side01_05_AverageColor_V"        "Side01_05_CenterOfMassX"        
## [509] "Side01_05_CenterOfMassY"         "Side01_05_CenterOfMassDistance" 
## [511] "Side01_05_H_Mean"                "Side01_05_H_Median"             
## [513] "Side01_05_H_StDev"               "Side01_05_H_Q1"                 
## [515] "Side01_05_H_Q3"                  "Side01_05_brown(H_14_27)"       
## [517] "Side01_05_brown-yellow(H_28_35)" "Side01_05_yellow(H_36_43)"      
## [519] "Side01_05_yellow-green(H_44_57)" "Side01_05_green(H_58_99)"       
## [521] "Side01_05_green-cyan(H_100_120)" "Side01_05_cyan-blue(H_121_142)" 
## [523] "Side01_05_blue(H_143_156)"       "Side01_05_HistoH_0_5"           
## [525] "Side01_05_HistoH_5_10"           "Side01_05_HistoH_10_15"         
## [527] "Side01_05_HistoH_15_20"          "Side01_05_HistoH_20_25"         
## [529] "Side01_05_HistoH_25_30"          "Side01_05_HistoH_30_35"         
## [531] "Side01_05_HistoH_35_40"          "Side01_05_HistoH_40_45"         
## [533] "Side01_05_HistoH_45_50"          "Side01_05_HistoH_50_55"         
## [535] "Side01_05_HistoH_55_60"          "Side01_05_HistoH_60_65"         
## [537] "Side01_05_HistoH_65_70"          "Side01_05_HistoH_70_75"         
## [539] "Side01_05_HistoH_75_80"          "Side01_05_HistoH_80_85"         
## [541] "Side01_05_HistoH_85_90"          "Side01_05_HistoH_90_95"         
## [543] "Side01_05_HistoH_95_100"         "Side01_05_HistoH_100_105"       
## [545] "Side01_05_HistoH_105_110"        "Side01_05_HistoH_110_115"       
## [547] "Side01_05_HistoH_115_120"        "Side01_05_HistoH_120_125"       
## [549] "Side01_05_HistoH_125_130"        "Side01_05_HistoH_130_135"       
## [551] "Side01_05_HistoH_135_140"        "Side01_05_HistoH_140_145"       
## [553] "Side01_05_HistoH_145_150"        "Side01_05_HistoH_150_155"       
## [555] "Side01_05_HistoH_155_160"        "Side01_05_HistoH_160_165"       
## [557] "Side01_05_HistoH_165_170"        "Side01_05_HistoH_170_175"       
## [559] "Side01_05_HistoH_175_180"        "Side01_05_HistoH_180_185"       
## [561] "Side01_05_HistoH_185_190"        "Side01_05_HistoH_190_195"       
## [563] "Side01_05_HistoH_195_200"        "Side01_05_HistoH_200_205"       
## [565] "Side01_05_HistoH_205_210"        "Side01_05_HistoH_210_215"       
## [567] "Side01_05_HistoH_215_220"        "Side01_05_HistoH_220_225"       
## [569] "Side01_05_HistoH_225_230"        "Side01_05_HistoH_230_235"       
## [571] "Side01_05_HistoH_235_240"        "Side01_05_HistoH_240_245"       
## [573] "Side01_05_HistoH_245_250"        "Side01_05_HistoH_250_255"       
## [575] "Side01_05_Greennes_Mean"         "Side01_05_Greennes_Deviation"   
## [577] "Side01_05_BarcodeEnabled"        "Side01_05_BarcodeFound"         
## [579] "row1"                            "area"                           
## [581] "height"                          "width"                          
## [583] "circularity"                     "compactness"                    
## [585] "contlength"                      "convexity"                      
## [587] "rectangularity"                  "anisometry"                     
## [589] "bulkiness"                       "struct_factor"                  
## [591] "outer_radius"                    "inner_radius"                   
## [593] "dist_mean"                       "dist_deviation"                 
## [595] "roundness"                       "holes_num"                      
## [597] "areaInMm2"                       "heightInMm"                     
## [599] "widthInMm"                       "Convex_Hull_Area"               
## [601] "AverageColor_H"                  "AverageColor_S"                 
## [603] "AverageColor_V"                  "CenterOfMassX"                  
## [605] "CenterOfMassY"                   "CenterOfMassDistance"           
## [607] "H_Mean"                          "H_Median"                       
## [609] "H_StDev"                         "H_Q1"                           
## [611] "H_Q3"                            "brown(H_14_27)"                 
## [613] "brown-yellow(H_28_35)"           "yellow(H_36_43)"                
## [615] "yellow-green(H_44_57)"           "green(H_58_99)"                 
## [617] "green-cyan(H_100_120)"           "cyan-blue(H_121_142)"           
## [619] "blue(H_143_156)"                 "HistoH_0_5"                     
## [621] "HistoH_5_10"                     "HistoH_10_15"                   
## [623] "HistoH_15_20"                    "HistoH_20_25"                   
## [625] "HistoH_25_30"                    "HistoH_30_35"                   
## [627] "HistoH_35_40"                    "HistoH_40_45"                   
## [629] "HistoH_45_50"                    "HistoH_50_55"                   
## [631] "HistoH_55_60"                    "HistoH_60_65"                   
## [633] "HistoH_65_70"                    "HistoH_70_75"                   
## [635] "HistoH_75_80"                    "HistoH_80_85"                   
## [637] "HistoH_85_90"                    "HistoH_90_95"                   
## [639] "HistoH_95_100"                   "HistoH_100_105"                 
## [641] "HistoH_105_110"                  "HistoH_110_115"                 
## [643] "HistoH_115_120"                  "HistoH_120_125"                 
## [645] "HistoH_125_130"                  "HistoH_130_135"                 
## [647] "HistoH_135_140"                  "HistoH_140_145"                 
## [649] "HistoH_145_150"                  "HistoH_150_155"                 
## [651] "HistoH_155_160"                  "HistoH_160_165"                 
## [653] "HistoH_165_170"                  "HistoH_170_175"                 
## [655] "HistoH_175_180"                  "HistoH_180_185"                 
## [657] "HistoH_185_190"                  "HistoH_190_195"                 
## [659] "HistoH_195_200"                  "HistoH_200_205"                 
## [661] "HistoH_205_210"                  "HistoH_210_215"                 
## [663] "HistoH_215_220"                  "HistoH_220_225"                 
## [665] "HistoH_225_230"                  "HistoH_230_235"                 
## [667] "HistoH_235_240"                  "HistoH_240_245"                 
## [669] "HistoH_245_250"                  "HistoH_250_255"                 
## [671] "Greennes_Mean"                   "Greennes_Deviation"             
## [673] "BarcodeEnabled"                  "BarcodeFound"

For now - let’s focus only on the projected shoot area from the 6 side views and one top view:

want <- c("Side01_00_area", "Side01_01_area", "Side01_02_area", "Side01_03_area", "Side01_04_area", "Side01_05_area", "area")
RGB_Area <- subset(RGB, RGB$measurement_name %in% want)
RGB_Area

Awesome! Now - Let’s separate the file_name into individual sections - including timestamp, trayID and so on.

strsplit(RGB_Area$file_name[1], "_")
## [[1]]
## [1] "20250119-130728" "37937626480640"  "00039997"        "010191"         
## [5] "079700"          "Side01.xml"

1st element is timestamp (YYYMMDD-HHMMSS), then some unknown ID, then tray ID, experiment ID, some other unknown ID and side.xml file

We will need timestamp and trayID for this experiment:

timestamp <- strsplit(RGB_Area$file_name[1], "_")[[1]][1]
tray.ID <- strsplit(RGB_Area$file_name[1], "_")[[1]][3]
timestamp
## [1] "20250119-130728"
tray.ID
## [1] "00039997"

Now let’s loop it into all of the rows of our dataset:

dim(RGB_Area)
## [1] 5894    4
for(i in 1:nrow(RGB_Area)){
  RGB_Area$timestamp[i]  <- strsplit(RGB_Area$file_name[i], "_")[[1]][1]
  RGB_Area$tray.ID[i] <- strsplit(RGB_Area$file_name[i], "_")[[1]][3]
}
RGB_Area$tray.ID <- as.numeric(as.character(RGB_Area$tray.ID))
unique(RGB_Area$tray.ID)
##  [1] 39997 39998 39999 40000 40001 40002 40003 40004 40005 40006 40007 40008
## [13] 40009 40010 40011 40012 40013 40014 40015 40016 40017 40018 40019 40020
## [25] 40021 40022 40023 40024 40025 40026 40027 40028 40029 40030 40031 40032
## [37] 40033 40034 40035 40036 40037 40038 40039 40040 40041 40042 40043 40044
## [49] 40045 40046 40047 40048 40049 40050 40051 40052 40053 40054 40055 40056

OK - I have added these numbers manually to ccorrespond to the Tray01 … Tray60 in the decoding sheet for this experiment. So let’s load this:

decode <- read.csv("20250120_SarahK__Batch 3_coding.csv")
decode
decode <- decode[,c(7,2,5:6)]
colnames(decode)[1] <- "tray.ID"
decode

OK cool cool - now let’s fuse it with the RGB data based on the tray.ID

unique(RGB_Area$tray.ID)
##  [1] 39997 39998 39999 40000 40001 40002 40003 40004 40005 40006 40007 40008
## [13] 40009 40010 40011 40012 40013 40014 40015 40016 40017 40018 40019 40020
## [25] 40021 40022 40023 40024 40025 40026 40027 40028 40029 40030 40031 40032
## [37] 40033 40034 40035 40036 40037 40038 40039 40040 40041 40042 40043 40044
## [49] 40045 40046 40047 40048 40049 40050 40051 40052 40053 40054 40055 40056
RGB2 <- merge(RGB_Area, decode, by= "tray.ID", all=T)
RGB2

Now - let’s keep onnly things that we would like to and get rid of unnecessary stuff

library(reshape2)
RGB_Area2 <- RGB2[,c(1, 6:9,4,5)]

RGB_Area2$measurement_value <- as.numeric(RGB_Area2$measurement_value)
nona.RGB_Area <- na.omit(RGB_Area2)
nona.RGB_Area

And now - it will be easier to summarize values that are in individual collumns rather than rows - so let’s cast the data first

nona.RGB_Area <- dcast(nona.RGB_Area, timestamp + TrayInfo + PlantID + PlantName + tray.ID ~ measurement_name)
## Using measurement_value as value column: use value.var to override.
nona.RGB_Area

now let’s summarize the area from top view and 6 different angles into one value:

nona.RGB_Area$Area.all <- nona.RGB_Area$area + nona.RGB_Area$Side01_00_area + nona.RGB_Area$Side01_01_area + nona.RGB_Area$Side01_02_area + nona.RGB_Area$Side01_03_area + nona.RGB_Area$Side01_04_area + nona.RGB_Area$Side01_05_area
nona.RGB_Area

One last remaining thing would be to resolve the timestamp into the “Day of experiment”. First let’s split it into a date and time:

# date
strsplit(nona.RGB_Area$timestamp[1], "-")[[1]][1]
## [1] "20250119"
# time
strsplit(nona.RGB_Area$timestamp[1], "-")[[1]][2]
## [1] "130728"

now for all of the rows:

for(i in 1:nrow(nona.RGB_Area)){
  nona.RGB_Area$date[i] <-  strsplit(nona.RGB_Area$timestamp[i], "-")[[1]][1]
  nona.RGB_Area$time[i] <-  strsplit(nona.RGB_Area$timestamp[i], "-")[[1]][2]
}

nona.RGB_Area

Now - let’s see how it looks like!

plot the RGB data

library(ggplot2)
nona.RGB_Area$date <- as.factor(nona.RGB_Area$date)
unique(nona.RGB_Area$tray_id)
## NULL
lgraph <- ggplot(data=nona.RGB_Area, aes(x= date, y=Area.all, group = tray.ID)) 
lgraph <- lgraph + geom_line(alpha = 0.7) 
lgraph <- lgraph + ylab("digital biomass") + xlab("days after stress")
lgraph

The Parthenium plants were loaded on Jan. 20th at around 13:00 and they were not imaged before 17:00 - so let’s calculate Time Of Experiment based on this - and remove all of the measurements that were before that time

nona.RGB_Area$day <- substr(nona.RGB_Area$date, 7, 8)
nona.RGB_Area$hour <- substr(nona.RGB_Area$time, 1, 2)
nona.RGB_Area

now let’s calculate time of experiment in hours:

nona.RGB_Area$TOE <- (as.numeric(as.character(nona.RGB_Area$day)) - 20)*24 + (as.numeric(as.character(nona.RGB_Area$hour)) - 17)
nona.RGB_Area <- subset(nona.RGB_Area, nona.RGB_Area$TOE > 0)
nona.RGB_Area
lgraph <- ggplot(data=nona.RGB_Area, aes(x= TOE, y=Area.all, group = tray.ID)) 
lgraph <- lgraph + geom_line(alpha = 0.7) 
lgraph <- lgraph + ylab("digital biomass") + xlab("hours of experiment")
lgraph

now - let’s try to add more info - such as specific treatment from the decoding file:

library(ggpubr)
nona.RGB_Area$Area.all <- as.numeric(as.character(nona.RGB_Area$Area.all))
nona.RGB_Area$TOE <- as.numeric(as.character(nona.RGB_Area$TOE))
nona.RGB_Area$TrayInfo <- as.factor(nona.RGB_Area$TrayInfo)
unique(nona.RGB_Area$TrayInfo)
## [1] Control Drought
## Levels: Control Drought
Area_graph <- ggplot(data=nona.RGB_Area, aes(x= TOE, y=Area.all, group = tray.ID, color = TrayInfo)) 
Area_graph <- Area_graph + geom_line(alpha = 0.7) 
Area_graph <- Area_graph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group= TrayInfo), alpha=0.3)
Area_graph <- Area_graph + stat_summary(fun=mean, aes(group= TrayInfo),  size=0.7, geom="line", linetype = "dashed")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Area_graph <- Area_graph + stat_compare_means(aes(group = TrayInfo), label = "p.signif", method = "t.test", hide.ns = TRUE)
Area_graph <- Area_graph + ylab("Digital Biomass") + xlab("Time of imaging (h)")
Area_graph
## Warning: Computation failed in `stat_compare_means()`
## Caused by error in `mutate()`:
## ℹ In argument: `p = purrr::map(...)`.
## Caused by error in `purrr::map()`:
## ℹ In index: 6.
## ℹ With name: x.17.
## Caused by error in `t.test.default()`:
## ! not enough 'x' observations

The reason we have these odd lines - is that some of the trays got imaged one hour later - which pulls average into totally different direction (aka - one sample average). In order to make sure that we are comparing like-with-like - we can implement splines - so we can “predict” the values for all time points - however - we need to make sure that we are not over-interpreting the data - as in - predicting on a time scale of minutes or hours - as we have imaged approximately every 24h.

Spline fitting for RGB data

So - how do we do it? Splines!!! Spline-who??? Sounds complicated. But it is not. First - let’s take one tray and calculate predicted spline values based on one tray:

# Create a vector 'hours' containing values from 0 to 288 (12 days of imaging)
days <- seq(0, 250, by = 12)
days
##  [1]   0  12  24  36  48  60  72  84  96 108 120 132 144 156 168 180 192 204 216
## [20] 228 240
# Subset the data for one tray 
temp <- subset(nona.RGB_Area, nona.RGB_Area$tray.ID == unique(nona.RGB_Area$tray.ID)[1])

# Convert the 'TOE' column in 'temp' from a factor to numeric
temp$TOE <- as.numeric(as.character(temp$TOE))

# Display the 'days' column from the 'temp' data frame
temp$TOE
##  [1]   1  15  28  96 117 124 141 174 184 207 215 221 239
# Fit a cubic smoothing spline to the 'TOE' and 'Area.all' data in the 'temp' data frame
plot.spl <- with(temp, smooth.spline(TOE, Area.all, df = 5))
# Create a scatterplot of 'Area.sum' against 'days' using data from 'temp'
plot(Area.all ~ TOE, data = temp)

# Add a blue line to the plot based on the cubic smoothing spline ('plot.spl')
lines(plot.spl, col = "blue")

# Add a red line to the plot by predicting values using the cubic smoothing spline ('plot.spl')
lines(predict(plot.spl, days), col = "red")

# Define a vector 'names' containing column names
names <- c(text = "tray.ID", "TrayInfo", "TOE", "Area.SUM")

# Create an empty data frame 'spline_data' to store the data
spline_data <- data.frame()

# Loop through each element 'k' in the 'names' vector
for (k in names) {
  # Create a new column in 'spline_data' with the name specified by 'k' and initialize it as character type
  spline_data[[k]] <- as.character()
}

spline_data
pred_temp <- predict(plot.spl, days)

# Display the predictions stored in 'pred_temp'
pred_temp
## $x
##  [1]   0  12  24  36  48  60  72  84  96 108 120 132 144 156 168 180 192 204 216
## [20] 228 240
## 
## $y
##  [1] 341482.3 349552.7 360811.2 378434.8 402299.9 430160.0 459733.0 488736.9
##  [9] 514889.7 536794.4 556590.5 576893.9 600168.2 628262.8 661072.0 698264.7
## [17] 739616.8 786150.8 839594.3 901440.5 969472.5
length(pred_temp$x)
## [1] 21
# Update the first 25 rows of the 'spline_data' data frame, setting the 4th column to 'pred_temp$x'
spline_data[1:21, 3] <- pred_temp$x

# Update the first 25 rows of the 'spline_data' data frame, setting the 5th column to 'pred_temp$y'
spline_data[1:21, 4] <- pred_temp$y

# Update the first 25 rows of the 'spline_data' data frame, setting the 1st column to 'temp$TrayID[1]'
spline_data[1:21, 1] <- temp$tray.ID[1]

# Update the first 25 rows of the 'spline_data' data frame, setting the 2nd column to 'temp$TrayInfo[1]'
spline_data[1:21, 2] <- as.character(temp$TrayInfo[1])

spline_data
# Create a copy of 'spline_data' and store it in 'final_spline'
final_spline <- spline_data
# check how many unique plant IDs we have 
all_plants <- unique(nona.RGB_Area$tray.ID)
length(all_plants)
## [1] 60

now let’s do it for all plants:

for (i in 2:60) {
  temp <- subset(nona.RGB_Area, nona.RGB_Area$tray.ID == unique(nona.RGB_Area$tray.ID)[i])

  # Check if 'temp' has more than 4 rows
  if (dim(temp)[1] > 4) {
    # Fit a cubic smoothing spline to 'days' and 'Area.sum' in 'temp'
    plot.spl <- with(temp, smooth.spline(TOE, Area.all, df = 5))

    # Generate predictions using the smoothing spline
    pred_temp <- predict(plot.spl, days)

    # Update specific columns in 'spline_data' with 'pred_temp' and 'temp' values
    spline_data[1:21, 3] <- pred_temp$x
    spline_data[1:21, 4] <- pred_temp$y
    spline_data[1:21, 1] <- temp$tray.ID[1]
    spline_data[1:21, 2] <- as.character(temp$TrayInfo[1])

    # Append 'spline_data' to 'final_spline'
    final_spline <- rbind(final_spline, spline_data)
  } else {
    # Set specific columns in 'spline_data' when 'temp' has <= 4 rows
    spline_data[1:21, 3] <- days
    spline_data[1:21, 4] <- 0
    spline_data[1:21, 1] <- temp$tray.ID[1]
    spline_data[1:21, 2] <- as.character(temp$TrayInfo[1])
  }
}

final_spline
# Convert the 'TOE' column in 'final_spline' to numeric type
final_spline$TOE <- as.numeric(as.character(final_spline$TOE))

# Convert the 'Area.SUM' column in 'final_spline' to numeric type
final_spline$Area.SUM <- as.numeric(as.character(final_spline$Area.SUM))

# Filter 'final_spline' to keep rows where 'Area.SUM' is greater than 1
final_spline <- final_spline[final_spline$Area.SUM > 1, ]

final_spline
library(ggsci)

# Convert 'Area.SUM' column to numeric type
final_spline$Area.SUM <- as.numeric(as.character(final_spline$Area.SUM))

# Convert 'day' column to a factor with numeric levels
final_spline$TOE <- as.factor(as.numeric(as.character(final_spline$TOE)))

# Create a line graph (Area_lgraph) using ggplot2
Area_lgraph <- ggplot(data = final_spline, aes(x = TOE, y = Area.SUM, group = tray.ID, color = TrayInfo)) 
Area_lgraph <- Area_lgraph + geom_line(alpha = 0.1)
Area_lgraph <- Area_lgraph + stat_summary(fun.data = mean_se, geom = "ribbon", linetype = 0, aes(group = TrayInfo), alpha = 0.3) 
Area_lgraph <- Area_lgraph + stat_summary(fun = mean, aes(group = TrayInfo), size = 0.7, geom = "line", linetype = "dashed") 
Area_lgraph <- Area_lgraph + stat_compare_means(aes(group = TrayInfo), label = "p.signif", method = "t.test", hide.ns = F) 
Area_lgraph <- Area_lgraph + labs(x = "Hours of Imaging", y = "Digital Biomass (a.u.)") + scale_color_d3("category10") + theme(legend.position = "bottom")
Area_lgraph

Cool - it looks good and the plants do differentiate between Control and Drought at the end. Let’s have a look if they also show difference between individual populations

First - let’s add all of the decoding information:

final_spline_deco <- merge(final_spline, decode, by = c("tray.ID", "TrayInfo"))
final_spline_deco
Area_lgraph2 <- ggplot(data = final_spline_deco, aes(x = TOE, y = Area.SUM, group = tray.ID, color = TrayInfo)) 
Area_lgraph2 <- Area_lgraph2 + geom_line(alpha = 0.1) + facet_grid(~PlantName)
Area_lgraph2 <- Area_lgraph2 + stat_summary(fun.data = mean_se, geom = "ribbon", linetype = 0, aes(group = TrayInfo), alpha = 0.3) 
Area_lgraph2 <- Area_lgraph2 + stat_summary(fun = mean, aes(group = TrayInfo), size = 0.7, geom = "line", linetype = "dashed") 
Area_lgraph2 <- Area_lgraph2 + stat_compare_means(aes(group = TrayInfo), label = "p.signif", method = "t.test", hide.ns = F) 
Area_lgraph2 <- Area_lgraph2 + labs(x = "Hours of Imaging", y = "Digital Biomass (a.u.)") + scale_color_d3("category10") + theme(legend.position = "bottom")
Area_lgraph2

Let’s be honest - this graph is a bit messy - with all of the NS above each timepoint. Let’s make it better by plotting p-value for each comparison below the graph.

First - let’s change TOE into a nummeric and re-plot the graph:

library(scales)

final_spline_deco$TOE <- as.numeric(final_spline_deco$TOE)

Area_lgraph2 <- ggplot(data = final_spline_deco, aes(x = TOE, y = Area.SUM, group = tray.ID, color = TrayInfo)) 
Area_lgraph2 <- Area_lgraph2 + geom_line(alpha = 0.1) + facet_grid(~PlantName)
Area_lgraph2 <- Area_lgraph2 + stat_summary(fun.data = mean_se, geom = "ribbon", linetype = 0, aes(group = TrayInfo), alpha = 0.3) 
Area_lgraph2 <- Area_lgraph2 + stat_summary(fun = mean, aes(group = TrayInfo), size = 0.7, geom = "line", linetype = "dashed") 
# removing this line - since we will plot p-values in a separate graph and thus dont need the compare_means() function
#Area_lgraph2 <- Area_lgraph2 + stat_compare_means(aes(group = TrayInfo), label = "p.signif", method = "t.test", hide.ns = F) 
Area_lgraph2 <- Area_lgraph2 + labs(x = "", y = "Digital Biomass (a.u.)") + scale_color_d3("category10") + theme(legend.position = "top") + scale_y_continuous(labels = scientific)
Area_lgraph2

OK - now let’s plot the p-values:

library("dplyr")
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Function to perform t-test and extract p-value
get_p_value <- function(final_spline_deco) {
  t.test(Area.SUM ~ TrayInfo, data = final_spline_deco)$p.value
}

# Calculate p-values for each genotype and timepoint
p_values <- final_spline_deco %>%
  group_by(TOE, PlantName) %>%
  summarise(p_value = get_p_value(cur_data())) %>%
  ungroup()
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `p_value = get_p_value(cur_data())`.
## ℹ In group 1: `TOE = 1` and `PlantName = "Australia"`.
## Caused by warning:
## ! `cur_data()` was deprecated in dplyr 1.1.0.
## ℹ Please use `pick()` instead.
## `summarise()` has grouped output by 'TOE'. You can override using the `.groups`
## argument.
# Display the p-values in a table
p_values$LOD <- -log10(p_values$p_value)
p_values
Area_pplot <- ggplot(p_values, aes(x = TOE, y = LOD)) 
Area_pplot <- Area_pplot + geom_line() + geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "red") 
Area_pplot <- Area_pplot + facet_wrap(~ PlantName, ncol = 6)
Area_pplot <- Area_pplot + labs(x = "Hours Of Imaging", y = "-log10(p-value)") 
Area_pplot <- Area_pplot + theme_minimal() + theme_bw() + theme(strip.text = element_blank(), strip.background = element_blank()) 
Area_pplot

Cool - now let’s combine these two graphs into one:

library(cowplot)
## 
## Attaching package: 'cowplot'
## The following object is masked from 'package:ggpubr':
## 
##     get_legend
Area_plot <- plot_grid(Area_lgraph2, Area_pplot, rel_heights = c(4,1), ncol = 1, align = "v", axis = "l")
Area_plot

Calculating Growth Rate based on RGB data:

Now - we dont see much sigificant differences accross Control and Drought - but let’s also calculate the growth rate for each of the plants - to see if we see differences in recorded change in biomass.

First - let’s do it for one plant - just to see if everything is working all right;

temp <- subset(final_spline_deco, final_spline_deco$tray.ID == unique(final_spline_deco$tray.ID[1]))
temp$Area.SUM <- as.numeric(temp$Area.SUM)
temp$TOE <- as.numeric(temp$TOE)
# plot the data
plot(temp$Area.SUM ~ temp$TOE) +
# Linear regression line is added to the scatterplot using the lm() function
abline(lm(temp$Area.SUM ~ temp$TOE))

## integer(0)

Let’s have a look at the linear model components:

# Fit a linear regression model to predict 'length' based on 'hours' in the 'temp' data frame
model <- lm(temp$Area.SUM ~ temp$TOE)
model
## 
## Call:
## lm(formula = temp$Area.SUM ~ temp$TOE)
## 
## Coefficients:
## (Intercept)     temp$TOE  
##      152521        21117

Extract the growth rate (GR) coefficient from the linear regression model

GR <- model$coefficients[2]
GR
## temp$TOE 
## 21116.76

Calculate the coefficient of determination (R-squared) for the model

R2 <- summary(model)$r.squared
R2
## [1] 0.9834507

Define vector ‘names’ containing column names for the ‘growth_data’ data frame

temp
names <- c(text = "tray.ID", "TrayInfo", "PlantName", "GR", "R2")

# Create an empty data frame 'growth_data' to store growth-related data
growth_data <- data.frame()

# Loop through each element 'k' in the 'names' vector
for (k in names) {
  # Create a new column in 'growth_data' with the name specified by 'k' and set as character type
  growth_data[[k]] <- as.character()
}

# Assign the 'ID' value from the 'temp' data frame to the first row, first column of 'growth_data'
growth_data[1, 1] <- temp$tray.ID[1]

# Assign the 'Accession' value from the 'temp' data frame to the first row, second column of 'growth_data'
growth_data[1, 2] <- as.character(temp$TrayInfo[1])

# Assign the 'Treatment' value from the 'temp' data frame to the first row, third column of 'growth_data'
growth_data[1, 3] <- temp$PlantName[1]

# Assign the growth rate (GR) to the first row, fourth column of 'growth_data'
growth_data[1, 4] <- GR

# Assign the coefficient of determination (R-squared, R2) to the first row, fifth column of 'growth_data'
growth_data[1, 5] <- R2

growth_data

Looks great! Now - let’s do this for all of the plants within this experiment:

# Create vector 'all_plants' containing unique 'ID' values from 'final_spline'
all_plants <- unique(final_spline_deco$tray.ID)

# Loop through each unique 'ID' in 'all_plants'
for (i in 1:length(all_plants)) {
  # Subset 'final_spline_deco' to select data for the current 'ID'
  temp <- subset(final_spline_deco, final_spline_deco$tray.ID == all_plants[i])
  temp$Area.SUM <- as.numeric(temp$Area.SUM)
  temp$TOE <- as.numeric(temp$TOE)

  # Fit a linear regression model to predict 'Area.SUM' based on 'day'
  model <- lm(temp$Area.SUM ~ temp$TOE)

  # Extract the growth rate (GR) coefficient from the linear regression model
  GR <- model$coefficients[2]

  # Calculate the coefficient of determination (R-squared, R2) for the model
  R2 <- summary(model)$r.squared

  # Populate 'growth_data' with relevant information for the current 'ID'
  growth_data[i, 1] <- temp$tray.ID[1]
  growth_data[i, 2] <-  as.character(temp$TrayInfo[1])
  growth_data[i, 3] <- temp$PlantName[1]
  growth_data[i, 4] <- GR
  growth_data[i, 5] <- R2
}

growth_data

Let’s fo a little clean up:

# Convert the 'GR' and 'R2' columns in 'growth_data' to numeric
growth_data$GR <- as.numeric(as.character(growth_data$GR))
growth_data$R2 <- as.numeric(as.character(growth_data$R2))

growth_data_clean <- subset(growth_data, growth_data$R2 > 0.7)
growth_data_clean <- subset(growth_data_clean, growth_data_clean$GR > 0)
growth_data_clean

Great - now we have all of this data - let’s plot it:

growth_data_clean$TrayInfo <- factor(growth_data_clean$TrayInfo, levels =c("Control", "Drought"))
GR_overall <- ggerrorplot(growth_data_clean, x = "TrayInfo", y = "GR", color = "TrayInfo", fill = "TrayInfo", facet.by = "PlantName",
                          desc_stat = "mean_sd", add = "jitter", ncol = 8,
                          xlab="", ylab= "Growth Rate (pixel / hour)", add.params = list(color = "darkgray")) + scale_color_d3("category10") 
GR_overall <- GR_overall + stat_compare_means(method = "aov", label.y = 35000)
GR_overall <- GR_overall + rremove("legend") + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
GR_overall

OK - now let’s save these two graphs as PDF:

library(cowplot)
pdf("Batch03.RGB_data_per_Population.pdf", width = 10, height = 10)
plot_grid(Area_plot, GR_overall, rel_heights = c(1, 0.7), labels = "AUTO", ncol = 1)
dev.off()
## quartz_off_screen 
##                 2

Before moving on - let’s save all of the data used for these plots:

write.csv(growth_data_clean, "Batch.03.GrowthRate.csv", row.names = F)
write.csv(final_spline_deco, "Batch.03.DigitalBiomass.csv", row.names = F)

moving ooooon….. let’s start a new notebook - since I have issues loadign the PS2 data from this experiment.