Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
481 views
in Technique[技术] by (71.8m points)

r - Modify package function

This is my first time trying this, so apologies if I get the terminology wrong. There's a package (snapCGH on bioconductor) that I'm using. I call one function, plotSegmentedGenome, which in turn calls genomePlot. Both functions are within the snapCGH namespace:

> environment(plotSegmentedGenome)
<environment: namespace:snapCGH>
> environment(genomePlot)
<environment: namespace:snapCGH>

I want to modify genomePlot. My first attempt consisted of simply running

> genomePlot

So I could get the code and create a new function from that. Two minor things I'd like to change. It labels the x-axis in mb whereas Id like it bp (so multiplying the labels but no the values plotted by 1000000). Secondly, it labels the x-axis additionally with the chromosome in a jarring red. Id like to remove that label totally. Saved this attempt as genomePlot.R and sourced it.

If I then run plotSegmentedGenome then nothing changes. So I presume it's still using the genomePlot function within its namespace. If I create my own copy of plotSegmentedGenome in the global env, then I get an error "Error: object 'chrominfo.Mb' not found". This is one of the arguments for plotSegmentedGenome which I suppose is created in the env.

I hope this makes sense and that there's a solution that isnt embarrisingly easy :)

ps: I read this, http://www.r-bloggers.com/environments-in-r/, which was interesting but not quite detailed enough to let me figure out how to do fix this. If only I could write

snapCGH$genomePlot <- customGenomePlot
or 
snapCGH:::genomePlot <- customGenomePlot

Update: Based on Redirect/intercept function calls within a package function

I tried

 library(proto)
  plotSegmentedGenome <- with(proto(environment( plotSegmentedGenome),  plotSegmentedGenome = snapCGH:: plotSegmentedGenome, genomePlot = genomePlot), my_genomePlot)

But I still received the error

 Error in plotSegmentedGenome(SegInfo.Hom.runDNAcopy, array = array, chrom.to.plot = 19,  : 
   object 'chrominfo.Mb' not found
  > 

It is calling my version of the function at least though, as it prints the message("its alive!") I stuck in my_genomePlot

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I finally found a solution that should work in all situations!

environment(customGenomePlot) <- asNamespace('snapCGH')
assignInNamespace("genomePlot", customGenomePlot, ns = "snapCGH")

The call to environment() assures that the function will be able to call other hidden functions from the package.

The call to assignInNamespace() assures that other functions from the package will call your updated version of the function.

It is possible that in certain situation, you need only one of these, but in general you need both. I struggled to find this general solution, found many other which are not working in some cases, like this (need opposite order), or this (misses the second part), or this (throws the error "cannot add bindings to a locked environment").


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...