5

I noticed there is a bug in a function from a package I want to use. An issue has been made on GitHub, but the creator hasn't adressed this yet, and I need the function as soon as possible.

Therefore I want to edit the code. Apparently this is possible by editing the source, repacking and installing the entire package, I can rewrite the function and reassign the namespace, but also possibly by just editing the function in the current session using trace().

I already found out I can do:

as.list(body(package:::function_inside_function))

The line I want to edit is located in the second step of the function.

Specifically, it is this line in the code I need to edit. I have to change ignore.case to ignore.case=TRUE. An example in case the link dies:

functionx(){if{...} else if(grepl("miRNA", data.type, ignore.case)) {...}}

I haven't really found a practical example on how to proceed from here, so can anyone show me an example of how to do this, or lead me to a practical example of using trace? Or perhaps reassigning the function to the namespace?

mhovd
  • 3,724
  • 2
  • 21
  • 47
MHeydt
  • 135
  • 8

2 Answers2

2

I faced a similar problem once and solved it using assignInNamespace(). I don't have your package installed so I cannot be sure this will work for you, but I think it should. You would proceed as follows:

Make the version of the function you want, as edited:

# I would just copy the function off github and change the offending line
readTranscripttomeProfiling <- function() {"Insert code here"}

# Get the problematic version of the function out of the package namespace
tmpfun <- get("readTranscripttomeProfiling", 
               envir = asNamespace("TCGAbiolinks"))

# Make sure the new function has the environment of the old 
# function (there are possibly easier ways to do this -- I like 
# to get the old function out of the namespace to be sure I can do 
# it and am accessing what I want to access)
environment(readTranscripttomeProfiling) <- environment(tmpfun)
# Replace the old version of the function in the package namespace
# with your new version
assignInNamespace("readTranscripttomeProfiling", 
                   readTranscripttomeProfiling, ns = "TCGAbiolinks")

I found this solution in another StackOverflow response, but cannot seem to find the original at the moment.

gfgm
  • 3,627
  • 14
  • 34
  • Thanks, I accepted the other answer, because it does what I was looking for myself. However, I also thought reassigning an edited function to the namespace was an option if trace() wasn't possible. I will play around with this to understand it better. – MHeydt Mar 29 '18 at 12:09
2

For your specific case, you could probably indeed work around it using trace.

From the link you provide I don't know why you speak of a function inside a function, but this should work:

# example
trace("grepl", tracer = quote(ignore.case <- TRUE))

grepl("hi", "Hi")
## Tracing grepl("hi", "Hi") on entry 
## [1] TRUE

# your case (I assume)
trace("readTranscriptomeProfiling", tracer = quote(ignore.case <- TRUE))

Note that this would be more complicated if the argument ignore.case that you want to fix wasn't already at the right position in the call.

RolandASc
  • 3,863
  • 1
  • 11
  • 30
  • I think your solution might do the trick without having to save the edited code somewhere and assigning it to namespace, so i'll accept this answer, thank you. And woops, I tought it was one big function, I was wrong. – MHeydt Mar 29 '18 at 12:35