poppr icon indicating copy to clipboard operation
poppr copied to clipboard

Cannot re-level strata of a snpclone object

Open Neato-Nick opened this issue 3 years ago • 1 comments

Please place an "x" in all the boxes that apply

  • [x] I have the most recent version of poppr and R
  • [x] I have found a bug
  • [ ] I want to request a new feature

Strata do not keep factor leveling. I noticed that snpclone objects immediately reset to their own leveling whenever a factor is releveled. In an MSN, I'd like the populations to appear in a specific order, so I tried to put the levels in the right order like I typically do for ggplot but that did not work

I don't know if this is solvable at least at the snpclone level, and I recognize this may be a few steps away from poppr's problem:

  • Adegenet: strata of genlight objects also cannot be releveled
  • Base plot: Do the factor levels even get used for plotting, or if I solve the re-leveling issue will the populations still be in the original order?

I'd appreciate any advice to go from here, thanks

library(poppr)
#> Loading required package: adegenet
#> Loading required package: ade4
#> Registered S3 method overwritten by 'spdep':
#>   method   from
#>   plot.mst ape
#> 
#>    /// adegenet 2.1.3 is loaded ////////////
#> 
#>    > overview: '?adegenet'
#>    > tutorials/doc/questions: 'adegenetWeb()' 
#>    > bug reports/feature requests: adegenetIssues()
#> Registered S3 method overwritten by 'pegas':
#>   method      from
#>   print.amova ade4
#> This is poppr version 2.9.2. To get started, type package?poppr
#> OMP parallel support: available

dat <- list(toto=c(1,1,0,0), titi=c(NA,1,1,0), tata=c(NA,0,1, NA))
x <- new("genlight", dat)
x <- as.snpclone(x)
strata(x) <- data.frame(ind = c("toto", "titi", "tata"), year = c(2003, 2001, 2002))
# Original levels
levels(strata(x)$year)
#> [1] "2003" "2001" "2002"
# Order I want the factor in for plotting
levels(factor(strata(x)$year, levels = c(2001, 2002, 2003)))
#> [1] "2001" "2002" "2003"
# Assign to that order
strata(x)$year <- factor(strata(x)$year, levels = c(2001, 2002, 2003))
# Assignment did not take
levels(strata(x)$year)
#> [1] "2003" "2001" "2002"

setPop(x) <- ~year
poppr.msn(x, bitwise.dist(x), showplot = TRUE)

#> $graph
#> IGRAPH 6c5624c UNW- 3 2 -- 
#> + attr: name (v/c), size (v/n), shape (v/c), pie (v/x), pie.color
#> | (v/x), color (v/c), label (v/c), weight (e/n), color (e/c), width
#> | (e/n)
#> + edges from 6c5624c (vertex names):
#> [1] toto--titi titi--tata
#> 
#> $populations
#> [1] "2003" "2001" "2002"
#> 
#> $colors
#>      2003      2001      2002 
#> "#4C00FF" "#00FF4D" "#FFFF00"

Created on 2021-07-06 by the reprex package (v2.0.0)

Neato-Nick avatar Jul 06 '21 17:07 Neato-Nick

Hi @Neato-Nick,

Sorry for the late reply. This is more of an adegenet, issue, but I will still tackle it here.

There are two solutions for this issue depending on the problem you are trying to solve:

  1. To adjust how the strata are plotted in the legend for the MSN, rearrange them in the MSN object
  2. if you want to re-level the strata for the data set itself so you don't have to constantly rearrange the levels, then the best method is to use the x@strata$year to set it directly (yes, I cringe at this because I spent years telling people to not use the slot directly, but this is literally the only way [see below])

Note: be careful because levels(x) <- sort(levels(x)) does not rearrange the levels like you want it to do, it re-assigns the levels, so your data will all be mis-labeled:

x <- factor(c("b", "a", "c"), levels = c("b", "a", "c"))
x
#> [1] b a c
#> Levels: b a c
levels(x) <- sort(levels(x))
x
#> [1] a b c
#> Levels: a b c

Created on 2021-07-24 by the reprex package (v2.0.0)

What you want is to recreate the factor all together:

x <- factor(c("b", "a", "c"), levels = c("b", "a", "c"))
x
#> [1] b a c
#> Levels: b a c
x <- factor(x, sort(levels(x)))
x
#> [1] b a c
#> Levels: a b c

Created on 2021-07-24 by the reprex package (v2.0.0)

Why does adegenet force the strata to be in the order of observation?

Honestly, I'm not sure. If you look at the code that controls strata()<-, you can see that it will force-reorder the data: https://github.com/thibautjombart/adegenet/blob/e03d87382117a5fcaa914928f8ec37dc72d267cd/R/strataMethods.R#L29-L44

You'll have to ask 2015 Zhian for why he thought that was a good idea, but I think the idea was that people would have prepared their data in a specific order before reading it into R, so we wanted to respect that ordering.

zkamvar avatar Jul 24 '21 20:07 zkamvar