Reputation: 4169
I have run some data through MCMCglmm to produce 16 chains - they are .rda files each with the following with a structure looking a little something like this (the list has 16 components, e.g. Sol, VCV, DIC.., I've only posted the top part because it's quite long) and in total there are 16 of these list (one per chain):
> dput(lapply(chain_shortA1, function(x) head(x,3))[1])
structure(list(Sol = structure(c(1.04619275548612, 1.05064026996843,
1.0508443605213, 1.05060001081438, 25.347877898399, 23.9721841898718,
25.137209308421, 23.7787279045151, 65.739413601812, 63.8638016616824,
65.9364721911843, 65.2303675767507, -0.133519658555997, -0.140548052135273,
-0.135612305268296, -0.141013350017602, 29.0450402791412, 29.2720730875153,
27.966162882396, 28.8481791445811, 50.6246755414177, 49.9310506192269,
52.2747936783417, 50.0815610028321), .Dim = c(4L, 6L), .Dimnames = list(
NULL, c("(Intercept)", "traitcl_f", "traitls_f", "traitbs_m",
"traitcl_m", "traitls_m")), mcpar = c(101, 131, 10), class = "mcmc")), .Names = "Sol")
I need to extract and store a number of these items for each chain, e.g. for just two chains and two values there are four combinations:
chain_shortA1_DIC = chain_shortA1$DIC
chain_shortA1_VCV = chain_shortA1$VCV
chain_shortA2_DIC = chain_shortA2$DIC
chain_shortA2_VCV = chain_shortA2$VCV
I think this can be done by first of all providing a list of the chains and values I want:
chains = list ("chain_shortA1","chain_shortA2")
values = list ("DIC", "VCV")
And then running it through a loop to produce all four items. However, I'm struggling with the loop part (I'm not the most fluent loop writer). This is my current attempt but it doesn't do what I had hoped for:
for (i in 1:length(chains)){
eval( parse( text = paste(chains[i], "$", values[i], sep = "")))
}
As a proof of principle, the script to print the value within the loop does work:
> eval( parse( text = paste(chains[1], "$", values[1], sep = "")))
[1] 125861.2
Furthermore, when I try the following I am also getting problems (each object should be stored as 'chain'_'value' e.g. chain_shortA1_DIC, as above)
for (i in 1:length(chains)){
paste(chains[i],"_",values[i]) = eval( parse( text = paste(chains[i], "$", values[i], sep = "")))
}
If anything is unclear please comment and I'll edit/respond to clarify
Upvotes: 2
Views: 110
Reputation: 545923
Your loop is correct, but it doesn’t store the result anywhere.
But it’s also more complicated than necessary – you don’t need parse
/eval
here because x$y
is equivalent to x[['y']]
. So you can do this:
chains[i][[values[i]]]
… and assign the result to some variable:
assign(paste(chains[i], values[i], sep = '_'), chains[i][[values[i]]])
But I don’t think it’s a great idea to create such variables in the first place: instead of having a variable of the format chain_shortA1_DIC
you can just as well use a nested list, and this seems to be the original data format you already have to begin with.
As an aside, paste(…, sep = '')
is equivalent to paste0(…)
. But in your case you even do have a separator, because you wrote paste(…, '$', …, sep ='')
. This works, of course, but the way paste
is intended to be used is like this: paste(…, …, sep = '$')
.
Upvotes: 2