class: center, middle, inverse, title-slide .title[ # GxE Analysis Workshop ] .author[ ### Ellena Girma ] .date[ ### 2022/05/27 (updated: 2022-10-12) ] --- class: middle, center ### Hello, Everyone! -- #### My name is Ellena Girma and I am a breeding data systems and analytics specialist at the Alliance Bioversity International - CIAT. -- #### The goal of this presentation is to demonstrate how R can be used to run GxE analyses. -- #### I will take you through the workflow that I use to run my GxE analysis for multi environment trials. For each part, I will cover the main functions that I use and what outputs/results you can expect to get. --- ## Introduction to GxE Studies .pull-left[ #### Understanding Genotype-Environment (GxE) Interaction * GXE interaction: the interaction of genotypes and environmental conditions and its joint effect on the traits of interest * Is there a pattern of phenotypic expression of a trait across various environmental conditions? ] -- .pull-right[ #### Selecting & recommending genotypes that have wider or more specific adaptation across various environmental conditions * Stability: Does the performance of the genotype stay the same across environments? * Yield Production: Does the genotype perform well across environments? ] --- ## My Workflow #### In this presentation I will be sharing the process I use to get from raw data to results. I will be focusing on the response variable yield, but the code I use can be altered for other response variables too. Workflow: * Data Preparation * Exploratory Data Analysis * Means and High Yielding Genotypes & Locations * Analysis of Variance (ANOVA) * GGE Biplots * Stability Analysis * Additive Main-Effects Multiplicative Interaction (AMMI) --- class: middle, center ## Let's take a quick tour of R. --- class: middle, center ## For this workshop, we'll be focusing on the metan package. --- ## Loading Packages and Importing Data ```r #loading metan package into workspace #for analysis library(metan) #loading tidyverse package into workspace #for data manipulation functions library(tidyverse) #importing a csv file using the read.csv() function bean_data <- read.csv(here("GxE-June2022", "csvfile.csv"), header=TRUE, colClasses = c(rep("factor", 3), rep("numeric", 5))) ``` --- class: middle ## Exploratory Data Analysis (EDA) ### Exploring and summarizing datasets using summary statistics and plots/data visualization methods. -- Some EDA tasks: * finding outliers and missing values * looking at how our data is distributed * looking at the relationship between variables * getting summary statistics for each variable of interest --- ## Summary Statistics .panelset[ .panel[.panel-name[R Code] ```r #descriptive stats using metan package ds_all <- desc_stat(bean_data, stats= "main") ``` ] .panel[.panel-name[desc_stats output] ```r print(ds_all) ``` ``` ## # A tibble: 5 × 10 ## variable cv max mean median min sd.amo se ci.t n.valid ## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> ## 1 DF 7.02 48 39.5 39 33 2.77 0.093 0.182 891 ## 2 pods.plant 48.1 46.6 14.8 13.4 2.6 7.11 0.238 0.467 891 ## 3 seeds.pod 21.3 7.6 4.82 4.8 2.6 1.02 0.0343 0.0673 891 ## 4 sw 32.9 67 35.2 35 15.3 11.6 0.389 0.763 891 ## 5 yield 43.0 5153. 1754. 1602. 498. 754. 25.3 49.6 891 ``` ] ] --- #### Checking for outliers: Plots .panelset[ .panel[.panel-name[Code] This is for the variable yield. To get potential outliers for another variable, set the var argument to the variable name. ```r #Checking for potential outliers in yield variable find_outliers(bean_data, var = yield, plots =T) ``` ``` ## Trait: yield ## Number of possible outliers: 37 ## Line(s): 10 28 32 35 58 66 68 69 74 75 84 93 109 127 131 134 157 165 167 168 173 174 183 192 208 209 226 230 233 256 264 266 267 272 273 282 291 ## Proportion: 4.3% ## Mean of the outliers: 4314.67 ## Maximum of the outliers: 5152.6 | Line 208 ## Minimum of the outliers: 3241.9 | Line 28 ## With outliers: mean = 1754.348 | CV = 42.991% ## Without outliers: mean = 1643.421 | CV = 32.131% ``` ] .panel[.panel-name[Plot] ```r find_outliers(bean_data, var = yield, plots =T) ``` ``` ## Trait: yield ## Number of possible outliers: 37 ## Line(s): 10 28 32 35 58 66 68 69 74 75 84 93 109 127 131 134 157 165 167 168 173 174 183 192 208 209 226 230 233 256 264 266 267 272 273 282 291 ## Proportion: 4.3% ## Mean of the outliers: 4314.67 ## Maximum of the outliers: 5152.6 | Line 208 ## Minimum of the outliers: 3241.9 | Line 28 ## With outliers: mean = 1754.348 | CV = 42.991% ## Without outliers: mean = 1643.421 | CV = 32.131% ``` <img src="index_files/figure-html/yield-outliers-plots-1.png" width="504" /> ] ] --- ### Checking for Outliers: Looking at Data Points Let's take a look at which data point are the outliers. Are they all the same location or same genotypes? .panelset[ .panel[.panel-name[Code] ```r #potential outliers yield_outliers <- c(10, 28, 32, 35, 58, 66, 68, 69, 74 ,75, 84, 93, 109, 127, 131, 134, 157, 165, 167, 168, 173, 174, 183, 192, 208, 209, 226, 230, 233, 256, 264, 266, 267, 272, 273, 282, 291) yo <- bean_data %>% slice(yield_outliers) %>% arrange(Genotype) %>% slice(1:15) yo ``` ] .panel[.panel-name[Output] ``` ## Site Rep Genotype DF pods.plant seeds.pod sw yield ## 1 Selian 1 Cheupe 44 44.8 7.6 33 5085.3 ## 2 Selian 2 Cheupe 44 46.2 7.4 33 5127.8 ## 3 Selian 3 Cheupe 43 46.6 6.8 33 5152.6 ## 4 Selian 3 Chumba Neroza 38 15.4 5.8 31 3478.7 ## 5 Selian 1 Kanade 38 24.2 5.4 42 3241.9 ## 6 Selian 2 Kanade 38 23.8 5.4 42 3245.4 ## 7 Selian 3 Kanade 39 24.8 5.4 42 3291.5 ## 8 Selian 1 Katuku2 39 36.2 5.2 40 4309.2 ## 9 Selian 2 Katuku2 39 35.2 5.0 40 4256.0 ## 10 Selian 3 Katuku2 39 35.0 5.4 40 4245.4 ## 11 Selian 1 Kikobe 39 35.2 6.2 27 3306.3 ## 12 Selian 2 Kikobe 39 36.8 6.4 27 3285.1 ## 13 Selian 3 Kikobe 39 34.0 5.8 27 3355.9 ## 14 Selian 1 Nyeupe Kubwa 39 27.6 5.8 35 4419.1 ## 15 Selian 2 Nyeupe Kubwa 39 27.0 6.2 35 4298.6 ``` ] ] --- ## Grand Mean Yield of Genotypes Across Locations We can see the grand mean yield for each genotype across all three locations using the means_by() function. .panelset[ .panel[.panel-name[R Code] ```r #getting means by Genotype mg <- means_by(bean_data, Genotype) #Creating a new object with Ordered Means by Genotype mg_y <- mg %>% select(Genotype, yield) %>% arrange(desc(yield)) ``` ] .panel[.panel-name[Table] ```r slice(mg_y, 1:10) ``` ``` ## # A tibble: 10 × 2 ## Genotype yield ## <fct> <dbl> ## 1 Cheupe 3144. ## 2 Selian 15 3086. ## 3 Ruondera 2906. ## 4 Nyeupe Kubwa 2894. ## 5 Selian 14 2778. ## 6 Uyole 84 2722. ## 7 Selian 05 2711. ## 8 Soya Mbeya 2680. ## 9 Kikobe 2546. ## 10 Jabeyila 2476. ``` ] ] --- ## Yield Means Across Genotypes at Each Location Now, let's take a look at the grand mean at each location using the means_by() function. .panelset[ .panel[.panel-name[Code] ```r #getting means for all variables by Location me <- means_by(bean_data, Site) #Creating a new object with Ordered Means by Location me_y <- me %>% select(Site, yield) %>% arrange(desc(yield)) ``` ] .panel[.panel-name[Output] ```r me_y ``` ``` ## # A tibble: 3 × 2 ## Site yield ## <fct> <dbl> ## 1 Selian 2336. ## 2 Uyole 1579. ## 3 SUA 1347. ``` ] ] --- ## Top Performers at Each Location We can use the ge_winners() function to get the top performing genotype at each location across all response variables. ```r #top performing genotype in each env for yield win <- ge_winners(.data = bean_data, env = Site, gen = Genotype, resp = c(DF, pods.plant, seeds.pod, sw, yield), type = "winners") ``` ```r print(win) ``` ``` ## # A tibble: 3 × 6 ## ENV DF pods.plant seeds.pod sw yield ## <fct> <chr> <chr> <chr> <chr> <chr> ## 1 Selian Kamosi Cheupe Cheupe Lyamungo 90 Cheupe ## 2 SUA Kaisho kamugole Cheupe Kaempu Lyamungo 90 Jabeyila ## 3 Uyole Selian 15 Wifi Nyegela Cheupe Selian 15 Selian 14 ``` --- class: middle ## Analysis of Variance (ANOVA): Introduction #### Running an ANOVA allows us to * Evaluate differences in means among groups * see if genotype main effect, environment main effect and GxE interaction effect are significant * see which effect contributes most to the variation in performance of the different traits * Divide the variance into parts to estimate heritability #### The metan package provides <a href = "https://tiagoolivoto.github.io/metan/reference/index.html">many functions</a> that can be used to run ANOVA. Different functions are available based on the ANOVA type (one-way, two-way), type of model (fixed or mixed effect), etc. --- ## ANOVA for RCBD #### anova_joint() is the function used for combined site analysis. #### get the anova table for the response variable you want through anova_object_name$var_name$anova to .panelset[ .panel[.panel-name[R Code] ```r #Running joint anova for rcbd layout/plot design for all repsonse variables anova_joint(bean_data, env = "Site", gen = "Genotype", rep = "Rep", resp = everything()) ``` ] .panel[.panel-name[Yield ANOVA Table] ```r #getting the ANOVA table for yield rcbd_anova_yield <- rcbd_anova$yield$anova rcbd_anova_yield ``` ``` ## Source Df Sum Sq Mean Sq F value Pr(>F) ## 1 ENV 2.000000 158874976.4 79437488.20 3943.977619 0.000000e+00 ## 2 REP(ENV) 6.000000 759885.9 126647.66 6.287907 2.023559e-06 ## 3 GEN 98.000000 199047400.1 2031095.92 100.841517 1.451699e-310 ## 4 GEN:ENV 196.000000 135738882.9 692545.32 34.384059 1.554893e-232 ## 5 Residuals 588.000000 11843181.6 20141.47 NA NA ## 6 CV(%) 8.089650 NA NA NA NA ## 7 MSR+/MSR- 6.288451 NA NA NA NA ## 8 OVmean 1754.348260 NA NA NA NA ``` ] .panel[.panel-name[SW ANOVA Table] ```r #getting the ANOVA table for 100g seed weight rcbd_anova$sw$anova ``` ``` ## Source Df Sum Sq Mean Sq F value Pr(>F) ## 1 ENV 2.000000 27392.54795 1.369627e+04 51909.689778 0.0000000 ## 2 REP(ENV) 6.000000 2.41064 4.017733e-01 1.522745 0.1681973 ## 3 GEN 98.000000 85390.26909 8.713293e+02 3302.389579 0.0000000 ## 4 GEN:ENV 196.000000 6922.37872 3.531826e+01 133.858293 0.0000000 ## 5 Residuals 588.000000 155.14269 2.638481e-01 NA NA ## 6 CV(%) 1.458387 NA NA NA NA ## 7 MSR+/MSR- 2.315797 NA NA NA NA ## 8 OVmean 35.221212 NA NA NA NA ``` ] .panel[.panel-name[DF ANOVA Table] ```r #getting the ANOVA table for days to 75% flowering rcbd_anova$DF$anova ``` ``` ## Source Df Sum Sq Mean Sq F value Pr(>F) ## 1 ENV 2.000000 376.141414 188.070707 744.253705 7.959563e-162 ## 2 REP(ENV) 6.000000 6.747475 1.124579 4.450306 2.041800e-04 ## 3 GEN 98.000000 3804.080808 38.817151 153.611421 0.000000e+00 ## 4 GEN:ENV 196.000000 2515.858586 12.836013 50.796057 6.659219e-278 ## 5 Residuals 588.000000 148.585859 0.252697 NA NA ## 6 CV(%) 1.271386 NA NA NA NA ## 7 MSR+/MSR- 2.591123 NA NA NA NA ## 8 OVmean 39.538721 NA NA NA NA ``` ] ] --- ## Estimating Heritability #### Variance components can be calculated using the results from the ANOVA table. Using these variance components, we can estimate heritability. #### Use indexing to get the correct value from the anova table: anova_table[row_number, col_number] .panelset[ .panel[.panel-name[Calc Values 1] V of line = (Mean sq of treat - Mean sq of site:treat) / (site*rep) V of line*site = (Mean sq of site:treat - Mean sq of residual) / (rep) V of error = mean sq of residuals H2= Vline / Vline + Vline*site + Verror H2L= Vline/ (line + (Vline*site/nsites) + (Verror/nsite*nrep) ] .panel[.panel-name[Calc Values 2] ```r #variance of line Vl.yd <- (rcbd_anova_yield[3,4] - rcbd_anova_yield[4,4])/(3*3) #variance of line by site Vls.yd <- (rcbd_anova_yield[4,4] - rcbd_anova_yield[5,4])/(3) #variance of error Ve.yd <- rcbd_anova_yield[5,4] #Broad sense hertitability H2.yd <- Vl.yd/(Vl.yd + Vls.yd + Ve.yd) #Hertitability of Line Means H2L.yd <- Vl.yd/(Vl.yd + Vls.yd/3 + Ve.yd/(3*3)) ``` ] .panel[.panel-name[Combing Values into Table] ```r comb.site.vc <- cbind(rbind(Vl.yd, Vls.yd, Ve.yd, H2.yd, H2L.yd)) colnames(comb.site.vc) <- c("Yield") rownames(comb.site.vc) = c("V of Line", "V of Line x Site", "V of Error", "Broad Sense Heritability", "Heritability of Line Means") ``` ] .panel[.panel-name[Final Output] ```r print(comb.site.vc) ``` ``` ## Yield ## V of Line 1.487278e+05 ## V of Line x Site 2.241346e+05 ## V of Error 2.014147e+04 ## Broad Sense Heritability 3.784386e-01 ## Heritability of Line Means 6.590287e-01 ``` ] ] --- class: middle ## Genotype plus genotype-by-environment (GGE) Models -- #### Use the gge() function to create a gge model. -- #### First, the centering argument needs to be set to "environment" for us to get a GGE model. -- #### Then the svp argument can be used to create three types of gge models. Below are the three options: * svp = "environment" * svp = "genotype" * svp = "symmetrical" --- class: middle, center ## Genotype plus genotype-by-environment (GGE) Biplots -- #### Use the plot() function to create plots from your gge models. #### Use the type argument to choose the kind of plot you want. There are 10 types to choose from. --- ## Type argument in plot .pull-left[ 1 = Basic biplot. 2 = Mean performance vs. stability (gge biplots) or the The Average Tester Coordination view for genotype-trait and genotype-yield*trait biplots. 3 = Which-won-where. 4 = Discriminativeness vs. representativeness. 5 = Examine an environment (or trait/yield*trait combination). ] .pull-right[ 6 = Ranking environments (or trait/yield*trait combination). 7 = Examine a genotype. 8 = Ranking genotypes. 9 = Compare two genotypes. 10 = Relationship among environments (or trait/yield*trait combination). ] #### Take a look at the <a href = "https://tiagoolivoto.github.io/metan/reference/plot.gge.html">plot documentation</a> page for more information. --- class: middle, center # GGE Model 1 #Let's start with svp = "environment" --- .panelset[ .panel[.panel-name[Create Model] ```r gge_model <- gge(.data = bean_data, env = Site, gen = Gen_id, resp = yield, centering = "environment", svp = "environment") ``` ] .panel[.panel-name[Create Plot] Basic Biplot is a PC2 vs PC1 plot. Each environment will have a vector starting from the origin. The angle between environments gives you information about the correlation between the environments. ```r #creating the basic biplot plot(gge_model, type = 1) ``` ] .panel[.panel-name[Basic Biplot] ```r #call the name of the plot to view it gge_biplot ``` <img src="index_files/figure-html/plot-basic-biplot-1.png" width="504" /> ] ] --- .panelset[ .panel[.panel-name[R Code] The discriminativeness vs. representativeness plot is created by setting the type argument to 4. ```r plot(gge_model, type = 4) ``` ] .panel[.panel-name[Plot] Selian has the longest vector. We can look at yield performance at Selian and get more information about the yield of the genotypes than at SUA or Uyole. Uyole has the smaller angle to the Average Environment Axis (AEA). This makes it the most representative environment. ```r dvr ``` <img src="index_files/figure-html/plot-dvr-1.png" width="504" /> ] ] --- .panelset[ .panel[.panel-name[R Code] Let's compare the environments using another biplot. Set the type to 6 to rank environments and set type to 10 to visualize a clear relationship of the environments. ```r #creating plot 1: ranking environments plot(gge_model, type=6) #creating plot 2:relationship among environment plot(gge_model, type = 10) ``` ] .panel[.panel-name[Ranking Environment] ```r ranking_envrionment ``` <img src="index_files/figure-html/ranking-plot-1.png" width="504" /> ] .panel[.panel-name[Relationship Between Environments] ```r relationship ``` <img src="index_files/figure-html/comparing-env-biplots-1.png" width="504" /> ] ] --- class: middle, center # Now, for the second model, let's try svp = "genotype" --- ```r gge_model_gen <- gge(.data = bean_data, env = Site, gen = Gen_id, resp = yield, centering = "environment", svp = "genotype") ``` --- ##### Svp = "genotype" Biplots .panelset[ .panel[.panel-name[R Code] explain plot types ```r # mean performance vs stability plot(gge_model_gen, type =2) # Ranking genotype plot(gge_model_gen, type=8) ``` ] .panel[.panel-name[Mean vs Stability] ```r mean_vs_stability ``` <img src="index_files/figure-html/mean-perf-vs-stability-plot-1.png" width="504" /> ] .panel[.panel-name[Ranking Genotypes] ```r rank_genotype ``` <img src="index_files/figure-html/type-8-plot-1.png" width="504" /> ] ] --- class: middle, center # Finally, for the third model, let's look at svp = "symmetrical". --- .panelset[ .panel[.panel-name[Create Biplot] ```r gge_symmetrical <- gge(.data = bean_data, env = Site, gen = Gen_id, resp = yield, centering = "environment", svp = "symmetrical") ``` ] .panel[.panel-name[R Code] ```r # which won where plot(gge_symmetrical, type=3) #Comparing 2 genotypes compare_two_gen <- plot(gge_symmetrical, type=9, sel_gen1 = "15", sel_gen2 = "69") ``` ] .panel[.panel-name[Which Won Where] ```r which_won_where ``` <img src="index_files/figure-html/type-3-plot-1.png" width="504" /> ] .panel[.panel-name[Compare Genotypes] ```r compare_two_gen ``` <img src="index_files/figure-html/type-9-plot-1.png" width="504" /> ] ] --- class: middle ## Additive Main-Effects Multiplicative Interaction (AMMI) AMMI deals with average performances and specific performances/GxE interaction. * Addive Main-Effects: * Genotype Main Effect * Environment Main Effect * Multiplicative Interaction * Genotype * Environment Interaction Effect --- ##### Creating an AMMI Model .panelset[ .panel[.panel-name[AMMI Model] Use performs_ammi() to create an ammi object. From the ammi object, you can get: * ANOVA table * PCA * AMMI model scores * means of genotypes in the environments ```r ammi <- performs_ammi(.data = bean_data, env = Site, gen = Gen_id, rep = Rep, resp = yield) ``` ] .panel[.panel-name[AMMI ANOVA] ```r ammi$yield$ANOVA ``` ``` *## Source Df Sum Sq Mean Sq F value Pr(>F) Proportion *## 1 ENV 2 158874976.4 79437488.20 627.232194 1.078604e-07 NA *## 2 REP(ENV) 6 759885.9 126647.66 6.287907 2.023559e-06 NA *## 3 GEN 98 199047400.1 2031095.92 100.841517 1.451699e-310 NA *## 4 GEN:ENV 196 135738882.9 692545.32 34.384059 1.554893e-232 NA *## 5 PC1 99 112959941.7 1141009.51 56.650000 0.000000e+00 83.2 *## 6 PC2 97 22778941.2 234834.45 11.660000 0.000000e+00 16.8 *## 7 Residuals 588 11843181.6 20141.47 NA NA NA *## 8 Total 1086 642003209.7 591163.18 NA NA NA ## Accumulated ## 1 NA ## 2 NA ## 3 NA ## 4 NA ## 5 83.2 ## 6 100.0 ## 7 NA ## 8 NA ``` ] .panel[.panel-name[AMMI Plot] ```r residual_plots(ammi) ``` <img src="index_files/figure-html/ammi-plot-1.png" width="504" /> ] ] --- ###### AMMI Biplots .panelset[ .panel[.panel-name[Creating the plots] ```r #ab2, basic ammi biplot plot_scores(ammi) #b2, Produces an AMMI2 biplot (PC1 x PC2) to make inferences related to the interaction effects. plot_scores(ammi, type=2) #b2 polygon plot_scores(ammi, type=2, polygon=T) ``` ] .panel[.panel-name[ammi_biplot1] ```r ammi_biplot1 ``` <img src="index_files/figure-html/ab2-1.png" width="504" /> ] .panel[.panel-name[b2] ```r b2 ``` <img src="index_files/figure-html/b2-1.png" width="504" /> ] .panel[.panel-name[b2_polygon] ```r b2_polygon ``` <img src="index_files/figure-html/b2-polygon-1.png" width="504" /> ] ] --- class: middle, center # Ranks: Yield Output and Stability #### Ammi Stability Value (ASV) and Yield Stability Index (YSI) are the metrics I use/come across most frequently. Ranking genotypes using these metrics is useful because it takes into consideration both yield output and stability. -- .pull-left[ #### ASV: genotypes with low ASV values are more stable and vice versa. ] -- .pull-right[ #### YSI takes into account both stability and yield output making it a better method to identify high yielding and stable genotypes. Lower YSI have both high mean yield and stability traits. ] --- #### Use the <a href= "https://tiagoolivoto.github.io/metan/reference/ammi_indexes.html">ammi_indexes()</a> function to calculate many AMMI-based statistics. .panelset[ .panel[.panel-name[ASV] ```r ammi_index <- ammi_indexes(ammi, level = 0.95) ``` ] .panel[.panel-name[ASV Results] ```r ammi_index$yield$ASV ``` ``` ## [1] 0.3743284 105.7142141 45.3017281 5.5209325 24.1452122 8.3997479 ## [7] 41.8516322 36.1954736 13.1441321 9.6855204 10.0884941 15.5603091 ## [13] 21.9185126 11.5032871 2.6378536 24.4509217 39.6016949 18.0710260 ## [19] 3.2796301 13.9254193 22.7739710 14.3698118 1.7219150 6.1451389 ## [25] 7.1595452 105.4762409 17.5841386 33.7633071 14.7950173 24.0321075 ## [31] 22.0682420 31.6411401 12.4973625 16.1684393 7.8463305 45.7226331 ## [37] 23.1230903 18.4354299 40.2764680 30.1568250 21.7140351 29.5019066 ## [43] 8.2826783 15.2563748 21.2334733 25.5156696 37.4984548 8.6861028 ## [49] 43.0402788 7.0901911 13.8969691 6.8373741 35.8930326 69.3553828 ## [55] 2.9744217 29.8567655 2.9008277 32.5698178 8.8062425 52.7442305 ## [61] 8.5565234 18.1772123 82.1457799 15.3907617 115.9391135 141.8757472 ## [67] 22.2635780 23.0671911 11.6343117 33.3673054 15.0946263 8.8537557 ## [73] 79.4979963 5.2581231 37.8284771 12.3913684 28.5883873 15.7815954 ## [79] 28.5323632 32.5604059 2.9355086 6.7212823 84.5058132 37.2137729 ## [85] 14.4411885 20.4230591 24.3445197 11.7288386 35.5159709 6.6535237 ## [91] 15.2624635 55.0649012 140.7028315 13.8009329 8.8636252 7.4107872 ## [97] 24.8599914 26.9057554 58.4753660 ``` ] .panel[.panel-name[ASVR Results] ```r ammi_index$yield$ASV_R ``` ``` ## [1] 1 96 86 9 60 19 84 78 32 25 26 43 53 27 3 62 82 47 7 35 56 36 2 10 15 ## [26] 95 46 75 38 59 54 71 31 45 17 87 58 49 83 70 52 68 18 40 51 64 80 21 85 14 ## [51] 34 13 77 91 6 69 4 73 22 88 20 48 93 42 97 99 55 57 28 74 39 23 92 8 81 ## [76] 30 67 44 66 72 5 12 94 79 37 50 61 29 76 11 41 89 98 33 24 16 63 65 90 ``` ] .panel[.panel-name[YSI] ### YSI = RASV + RY ] ] --- class: middle # Follow Up Resources #### The link to this presentation will be emailed to you. #### Check out my <a href = "https://rforplantbreeders.netlify.app/"> blog </a> for more detailed written tutorials for plant breeders who want to learn how to use R. #### Current Posts: * <a href = "https://rforplantbreeders.netlify.app/posts/introduction-to-r-for-plant-breeding/"> Introduction to R </a> * <a href = "https://rforplantbreeders.netlify.app/posts/importing-data-into-r/"> Importing in R </a> --- class: middle, center # Any Questions? ### Thank you for attending this workshop. You can ask any questions you may have now.