Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include a text representation of an object (like dput) in a function call for reproducible research

I have created a shiny app in which a user can load a file and use the object as a function argument. I also print the code to run the function locally (so that I or anyone else could copy and paste to reproduce the result).

What I would like to do is to be able to use something like dput but to save the text representation of the loaded object to an object rather than the console. dput outputs to the console, but simply returns a copy of it's first argument. I can use deparse but it fails when the length of the object exceeds width.cutoff (default 60 and max 500).

The following hacky reproducible example illustrates. In it I use image as the example function. In my case I have other functions with more arguments.

#create example matrices
m2 <- matrix(1:4,2,2)
m4 <- matrix(1:4,4,4)

#this is what I want to recreate
image(z=m2,col=rainbow(4))
image(z=m4,col=rainbow(4))

#convert the matrices to their text representation
txtm2 <- deparse(m2)
txtm4 <- deparse(m4)

#create a list of arguments
lArgs2 <- list( z=txtm2, col=rainbow(4) )
lArgs4 <- list( z=txtm4, col=rainbow(4) )

#construct arguments list
vArgs2 <- paste0(names(lArgs2),"=",lArgs2,", ")
vArgs4 <- paste0(names(lArgs4),"=",lArgs4,", ")

#remove final comma and space
vArgs2[length(vArgs2)] <- substr(vArgs2[length(vArgs2)],0,nchar(vArgs2[length(vArgs2)])-2)
vArgs4[length(vArgs4)] <- substr(vArgs4[length(vArgs4)],0,nchar(vArgs4[length(vArgs4)])-2)

#create the text function call
cat("image(",vArgs2,")")
cat("image(",vArgs4,")")

#the 1st one when pasted works
image( z=structure(1:4, .Dim = c(2L, 2L)),  col=c("#FF0000FF", "#80FF00FF", "#00FFFFFF", "#8000FFFF") )

#the 2nd one gives an error because the object has been split across multiple lines
image( z=c("structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, ", "2L, 3L, 4L), .Dim = c(4L, 4L))"),  col=c("#FF0000FF", "#80FF00FF", "#00FFFFFF", "#8000FFFF") )

#In an ideal world I would also like it to work when I did this, but maybe that's asking too much
image(z=txtm2,col=rainbow(4))

I realise that the way I construct the function call is a hack, but when I looked at it a while ago I couldn't find a better way of doing. Open to any suggestions. Thanks.

like image 576
Andy Avatar asked Oct 15 '25 17:10

Andy


1 Answers

You can do something like :

## an object that you want to recreate
m2 <- matrix(1:4,2,2)
## use capture.output to save structure as a string in a varible
xx <- capture.output(dput(m2))

## recreate the object 
m2_ <- eval(parse(text=xx))
image(z=m2_,col=rainbow(4))
like image 106
agstudy Avatar answered Oct 18 '25 07:10

agstudy