(R) Burrow into function to change it with Trace() - r

I've built a large function which calls numerous gbm functions in a big loop. All I'm trying to do is increase the thickness of the tickmarks in rug() which is called by gbm.plot.
I was hoping to use (e.g.)
body(gbm.plot)[[24]][[4]][[3]][[3]][[3]][[3]][[2]]$ylab <- "change value"
From this page's examples, which I've used successfully elsewhere, but the section in question in gbm.plot is in an IF statement, so as.list doesn't nicely recurse the lines (because arguably it's all one huge long line). You can get to them by just manually [[trying]][[successive]][[combinations]] until you get to the right place, but since I'm trying to insert a piece of code , lwd=6 into a bracketed statement, rather than assigning a value to a named subobject, I'm not sure how to get trace to do this.
?trace says:
When the at argument is supplied, it can be a vector of integers referring to the substeps of the body of the function (this only works if the body of the function is enclosed in { ...}. In this case tracer is not called on entry, but instead just before evaluating each of the steps listed in at. (Hint: you don't want to try to count the steps in the printed version of a function; instead, look at as.list(body(f)) to get the numbers associated with the steps in function f.)
The at argument can also be a list of integer vectors. In this case, each vector refers to a step nested within another step of the function. For example, at = list(c(3,4)) will call the tracer just before the fourth step of the third step of the function
So I tried pasting the whole line with the lwd bit added in, hoping that it would overwrite it with the small addition:
trace (gbm.plot, quote(rug(quantile(data[, gbm.call$gbm.x[variable.no]], probs = seq(0, 1, 0.1), na.rm = TRUE),lwd=6)), at=c(22,4,7,3,3,3,2))
...as well as putting objects in & out of {brackets}, all to no avail. Does anyone know either the correct way of using trace for this, or can suggest a better way? Thanks
p.s. it needs to be done automatically with coding so users can load the function which will load the vanilla gbm functions from CRAN and then make tweaks as required.
EDIT: found a workaround. But generalisable question: how can one insert elements into an IF statemented part of a function? e.g. From
rug(quantile(data[, gbm.call$gbm.x[variable.no]], probs=seq(0, 1, 0.1), na.rm=TRUE))
to
rug(quantile(data[, gbm.call$gbm.x[variable.no]], probs=seq(0, 1, 0.1), na.rm=TRUE),lwd=6)

Related

Need help understandig the 'rep()' function

rep (2,5)
rep
Hello everyone, I am learning 'R' by watching a Udemy tutorial and I've been following along. Recently I learned seq() and rep() function. However, when I try to run the code written above I get an additional output. The code returns 2.2.2.2.2 and .Primitive("rep"). I am using Kaggle notebooks. Help me understand how this functions works, what is going wrong here, and what will happen if we provide multiple input as rep(2,3,4,5) or (1,2,3,4,6,8).
In R, rep is a function. It is designed to replicate its first argument a number of times equal to its second argument. Thus rep(2, 5) returns a vector of length 5 with each element as 2.
In R, functions are also objects, and when you input a function's name, R will return the something that tries to be useful by showing that the input is a function and providing the expected arguments. The .Primitive("rep") part tells you that rep is a primitive function, part of the base R code.
rep
function (x, ...) .Primitive("rep")
In this case, rep requires at least one argument x, which the object to be replicated. The ... indicates that it can take a number of other optional arguments. To learn about them, you can access the help file for rep with ?rep.
You can call rep with more arguments, but the behavior might not be what you expect.
By typing rep without any details, you are asking R to show you the internal "guts" of what the function does. You can learn more about it by typing ?rep. The manual is probably a lot for a beginner but if you scroll to the bottom you will see some useful examples.
I hope this help:
rep ("hi", 5) # print hi five times
rep(c("hi", "hello"), 3) # print the object holding hi and hello three times
rep(c("hi", "hello"), c(1, 2)) # print hi once and hello two times

How can I use a list of integers as the input to a function of one integer and get a list as an output?

Apologies for asking a trivial question, but I'm stumped. Here's the situation:
I have a function of three inputs fishCounter(data, x, y) where data is a matrix and both x and y are integers.
fishCounter is in memory and works completely fine when I call it manually (e.g. fishCounter(matrix(1:4,4,4), 1, 4)). Its output is a single integer.
The relevant data and value of x are in memory. x is simply 3, and we'll call the data trout.
I want R to spit out the list of results for every value of y from 1 to 20. Crudely, what I want is fishCounter(trout, 3, 1:20).
The way that R gives me this data (e.g. array, vector, list, etc) is not of interest, I just want the output however I can get it.
Everything that I've tried to get this has failed. I could of course use a for loop and append this all to a vector, but that seems like far too much effort.
My memory insists that there is a very simple way to get what I'm after. I'm sure that some version of replicate, apply or lapply will do this job.
What I want is a single function that will give me this result. For example, I was surprised when lapply(c(1:19), fishCounter(trout, 3, y) didn't work.
No libraries should be needed and I shouldn't need to code in any new functions. My memory insists that I'm either simply forgetting a function that's build in to R, have forgotten a term that would've got me the answer instantly from a search engine, or I've completely misunderstood the documentation on the three functions that I've listed earlier.
What have I forgotten?
Maybe you can try lapply like below, i.e.,
lapply(1:20, function(y) fishCounter(trout, 3, y))
or Vectorize over your function fishCounter, i.e.,
Vectorize(fishCounter)(trout, 3, 1:20)

not error, but not results either in R

I am trying to make a function in R that calculates the mean of nitrate, sulfate and ID. My original dataframe have 4 columns (date,nitrate, sulfulfate,ID). So I designed the next code
prueba<-read.csv("C:/Users/User/Desktop/coursera/001.csv",header=T)
columnmean<-function(y, removeNA=TRUE){ #y will be a matrix
whichnumeric<-sapply(y, is.numeric)#which columns are numeric
onlynumeric<-y[ , whichnumeric] #selecting just the numeric columns
nc<-ncol(onlynumeric) #lenght of onlynumeric
means<-numeric(nc)#empty vector for the means
for(i in 1:nc){
means[i]<-mean(onlynumeric[,i], na.rm = TRUE)
}
}
columnmean(prueba)
When I run my data without using the function(), but I use row by row with my data it will give me the mean values. Nevertheless if I try to use the function so it will make all the steps by itself, it wont mark me error but it also won't compute any value, as in my environment the dataframe 'prueba' and the columnmean function
what am I doing wrong?
A reproducible example would be nice (although not absolutely necessary in this case).
You need a final line return(means) at the end of your function. (Some old-school R users maintain that means alone is OK - R automatically returns the value of the last expression evaluated within the function whether return() is specified or not - but I feel that using return() explicitly is better practice.)
colMeans(y[sapply(y, is.numeric)], na.rm=TRUE)
is a slightly more compact way to achieve your goal (although there's nothing wrong with being a little more verbose if it makes your code easier for you to read and understand).
The result of an R function is the value of the last expression. Your last expression is:
for(i in 1:nc){
means[i]<-mean(onlynumeric[,i], na.rm = TRUE)
}
It may seem strange that the value of that expression is NULL, but that's the way it is with for-loops in R. The means vector does get changed sequentially, which means that BenBolker's advice to use return(.) is correct (as his advice almost always is.) . For-loops in R are a notable exception to the functional programming paradigm. They provide a mechanism for looping (as do the various *apply functions) but the commands inside the loop exert their effects in the calling environment via side effects (unlike the apply functions).

R: parameter in update function

Here is a snippet of R script doing beta regression on data "GasolineYield":
library("betareg")
data("GasolineYield", package = "betareg")
gy_logit <- betareg(yield ~ batch + temp, data = GasolineYield)
gy_logit4 <- update(gy_logit, subset = -4)
The 4th line magically deletes the 4th observation and update the fit automatically, but I don't quite understand the why this parameter works in the update function here, because I tried to look up the documentation by ?update, but couldn't find there's such parameter.
I'm curious about how to find right documentation in this case, because maybe I want to add some new observation instead of removing it. Any help?
subset in betareg works the same as subset in lm, therefore you can read lm documentation.
From the help file you can find:
subset an optional vector specifying a subset of observations to be used in the fitting process.
Hence by setting select=-4 you are lefting out the fourth row in the estimation.
update() contains the ... parameter, which means any parameters that are not matched in your call to update() are passed on to the function that does the estimation. In this case, that is betareg(), which does have the subset argument.
This type of thing is very common in R. Many higher-level function that call other user-visible functions will have the three dot parameter and pass any unmatched parameters on, so you have to search all the user-visible functions that get called in order to know all possible options.
You can check out the help file for the top level function (update() in this case) to get an idea of which functions get the leftover parameters.

Extracting the imaginary part of data from fft in R

I need to filter the imaginary part of a forward fourier transform.
I've been trying to use filter.complex (but R keeps saying function filter.complex does not exist)
I've used only filter, and I get the following warning message-
imaginary parts discarded in coercion
Please tell me if I'm missing something
This is an example:
x = fft(rec-mean(rec))/sqrt(length(rec))
y = fft(soi-mean(soi))/sqrt(length(soi))
fyx = filter.complex(y * Conj(x), rep(1, 15), sides = 2, circular = TRUE)
I tried unsuccessfully to find a filter.complex function (and I'm reasonably good art searching such things out.) I don't think it exists. I think you may have gotten a hold of some old S code that was set up for dispatching to the complex class. If I trim the command to just:
fyx = filter(y * Conj(x), rep(1, 15), sides = 2, circular = TRUE)
...., I get the identical message. It's apparently from the deeper code called at the C-level since that message is not visible in the R-code that appears when you just type "filter" at the command line. Searching with Google for the error message shows it's probably coming from: http://svn.r-project.org/R/trunk/src/main/coerce.c .
It is just a warning, and not necessarily evidence of wrong-doing on your part.
I figured out what was wrong. The function 'filter.complex' was not defined in any package.
So, I defined it as follows-
filter.complex=function(x,...){complex(real=filter(Re(x),...), imag=filter(Im(x),...))}
This filtered the imaginary part that I needed.

Resources