[R] Problem with creating a PCA graph in a loop
Ivan Krylov
|kry|ov @end|ng |rom d|@root@org
Wed May 8 09:16:38 CEST 2024
В Tue, 7 May 2024 16:57:14 +0200
gavin duley <gduley using gmail.com> пишет:
> aes(label=current_rownames,
> colour=wine.data.filt$Treatment
> )
As you've noticed, aes() remembers variables by their name and
environment, not by value:
str(ggplot2::aes(label = foo))
# List of 1
# $ label: language ~foo # <-- variable name recorded here
# and here is the environment
# ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
# - attr(*, "class")= chr "uneval"
One way to get around the problem is to ensure that the variables live
in different environments. Instead of making it a for loop, write a
function that would accept `i` and return a plot instead of assigning
it by name:
makeplot <- function(i) {
print(i)
wine.data.filt <- filter(wine.data,Time == i)
current_rownames <- rownames(wine.data.filt)
wine.data.filt.pca <- dudi.pca(wine.data.filt[3:11],
nf=6,
scannf=F)
wine.data_quanti_sup <- wine.data.filt[,12, drop = FALSE]
return(fviz_pca_ind(wine.data.filt.pca,
# <the rest of the plot expression is omitted>
)
}
individs <- lapply(levels(wine.data$Time), makeplot)
individs[[1]]
(In many languages, trying to use a variable as a variable name, while
possible, usually means you need to consider some kind of nested data
structure:
https://perldoc.perl.org/perlfaq7#How-can-I-use-a-variable-as-a-variable-name?
In R, this structure is a list.)
Why does this work? Calling a function creates a new environment every
time. The plots will all refer to the variable named current_rownames,
but the environments will be different:
attr((function() ggplot2::aes(label = foo))()$label, '.Environment')
# <environment: 0x5650ffc2bfd8>
attr((function() ggplot2::aes(label = foo))()$label, '.Environment')
# <environment: 0x5650ffc5c128>
attr((function() ggplot2::aes(label = foo))()$label, '.Environment')
# <environment: 0x5650ffc8a3d8>
Alternatively, supply a data= argument to geom_label_repel() and make
your mapping = aes(...) reference variables from the data (which will
be remembered), ignoring the environment (which is only referenced).
Something like the following should work, untested:
geom_label_repel(
mapping = aes(label = current_rownames, colour = Treatment),
data = data.frame(
current_rownames = current_rownames,
Treatment = wine.data.filt$Treatment
),
# more arguments here
)
--
Best regards,
Ivan
More information about the R-help
mailing list