R how to pass variable into a function inside tapply - r

Now my code is as follows:
common_timestamps = NULL
tapply(data$timestamps, data$date,
function(x, common_timestamps ) {
if(length(common_timestamps ) == 0) {
common_timestamps = x
} else {
date_time = intersect(common_timestamps, x)
}
return(common_timestamps)
},
common_timestamps
)
I want to get the common timestamps from the code in the above. I found each time in the loop, the common_timestamp is null and it did not return common_timestamp. What is wrong with code? I think my concept about passing
variables into function for R language might be right.
Could you correct my error and explain my error?
Thank you very much for your help.

Related

How to return event$data in rstudio/websocket

I am trying to extend websocket::Websocket with a method that sends some data and returns the message, so that I can assign it to an object. My question is pretty much identical to https://community.rstudio.com/t/capture-streaming-json-over-websocket/16986. Unfortunately, the user there never revealed how they solved it themselves. My idea was to have the onMessage method return the event$data, i.e. something like:
my_websocket <- R6::R6Class("My websocket",
inherit = websocket::WebSocket,
public = list(
foo = function(x) {
msg <- super$send(paste("x"))
return(msg)
} )
)
load_websocket <- function(){
ws <- my_websocket$new("ws://foo.local")
ws$onMessage(function(event) {
return(event$data)
})
return(ws)
}
my_ws <- load_websocket()
my_ws$foo("hello") # returns NULL
but after spending a good hour on the Websocket source code, I am still completely in the dark as to where exactly the callback happens, "R environment wise".
You need to use super assignment operator <<-. <<- is most useful in conjunction with closures to maintain state. Unlike the usual single arrow assignment (<-) that always works on the current level, the double arrow operator can modify variables in parent levels.
my_websocket <- R6::R6Class("My websocket",
inherit = websocket::WebSocket,
public = list(
foo = function(x) {
msg <<- super$send(paste("x"))
return(msg)
} )
)
load_websocket <- function(){
ws <- my_websocket$new("ws://foo.local")
ws$onMessage(function(event) {
return(event$data)
})
return(ws)
}
my_ws <- load_websocket()
my_ws$foo("hello")

if/else statement evaluating only else statement

Disclaimer: This is a question regarding an assignment for a Coursera course.
I'm having trouble coming up with a way to create a new column that differentiates between weekdays and weekends in my data set. I'm using a nested if/else statement within a for loop. The problem is the output makes every row 'weekday'. Does anyone see something glaringly wrong with my code? My end goal is to create a new factor variable that is either "weekend" or "weekday."
df4 <- mutate(df4, day = weekdays(df4$date))
for (i in df4$day) {
if(i %in% c("Saturday",'Sunday')) {
df4$day_type <- 'weekend'
} else {
df4$day_type <- 'weekday'
}
}
I modify a little bit of your code .(see below)
for (i in 1 : dim(df4)[1]) {
if(df4$day[i] %in% c('Saturday','Sunday')) {
df4$day_type[i] <- 'weekend'
} else {
df4$day_type[i] <- 'weekday'
}
}

Can R recognize the type of distribution used as a function argument?

Background
I have a simple function called TBT. This function has a single argument called x. A user can provide any type rdistribution_name() (e.g., rnorm(), rf(), rt(), rbinom() etc.) existing in R for argument x, EXCEPT ONE: "rcauchy()".
Question
I was wondering how R could recognize that a user has provided an rcauchy() as the input for x, and when this is the case, then R issues a warning message?
Here is my R code with no success:
TBT = function(x) {
if( x == rcauchy(...) ) { warning("\n\tThis type of distribution is not supported.") }
}
TBT( x = rcauchy(1e4) )
Error in TBT(rcauchy(10000)) : '...' used in an incorrect context
If you are expeciting them do call to random function when they call your function, you could so
TBT <- function(x) {
xcall <- match.call()$x
if (class(xcall)=="call" && xcall[[1]]=="rcauchy") {
warning("\n\tThis type of distribution is not supported.")
}
}
TBT( x = rcauchy(1e4) )
But this would not catch cases like
x <- rcauchy(1e4)
TBT( x )
R can't track where the data in the x variable came from

R: Collect intermediate output of recursive function

I have a recursive function that uses the output of the previous call as the input of the next call:
recurse_foo = function(input) {
if(identical(input, character(0))) return(NULL)
else {
uu = get_incremental_output(input) ## <-- interested in collecting this
return(recurse_foo(uu))
}
}
As is evident, the terminal output is not very interesting, and I am interested in collecting the intermediate output, but I cannot imagine that growing a global list or any other side effect would be elegant (which is the only thing I can think of).
Any other abstractions that might be useful here?
Thanks.
Specific example:
final_countdown = function(input) {
if (input/2 < 1) return(NULL)
else {
uu = input/2 # <-- interested in collecting this
print(uu)
return(final_countdown(uu))
}
}
final_countdown(100)
In this case, I am interested in collecting the sequence of uus that are printed.
This is a solution, if all intermediate outputs are of the same type:
final_countdown = function(input) {
if (input/2 < 1) return(NA)
else {
c(input, final_countdown(input/2))
}
}

Is there a way to run an expression on.exit() but only if completes normally, not on error?

I'm aware of the function on.exit in R, which is great. It runs the expression when the calling function exits, either normally or as the result of an error.
What I'd like is for the expression only to be run if the calling function returns normally, but not in the case of an error. I have multiple points where the function could return normally, and multiple points where it could fail. Is there a way to do this?
myfunction = function() {
...
on.exit( if (just exited normally without error) <something> )
...
if (...) then return( point 1 )
...
if (...) then return( point 2 )
...
if (...) then return( point 3 )
...
return ( point 4 )
}
The whole point of on.exit() is exactly to be run regardless of the exit status. Hence it disregards any error signal. This is afaik equivalent to the finally statement of the tryCatch function.
If you want to run code only on normal exit, simply put it at the end of your code. Yes, you'll have to restructure it a bit using else statements and by creating only 1 exit point, but that's considered good coding practice by some.
Using your example, that would be:
myfunction = function() {
...
if (...) then out <- point 1
...
else if (...) then out <- point 2
...
else if (...) then out <- point 3
...
else out <- point 4
WhateverNeedsToRunBeforeReturning
return(out)
}
Or see the answer of Charles for a nice implementation of this idea using local().
If you insist on using on.exit(), you can gamble on the working of the traceback mechanism to do something like this :
test <- function(x){
x + 12
}
myFun <- function(y){
on.exit({
err <- if( exists(".Traceback")){
nt <- length(.Traceback)
.Traceback[[nt]] == sys.calls()[[1]]
} else {FALSE}
if(!err) print("test")
})
test(y)
}
.Traceback contains the last call stack resulting in an error. You have to check whether the top call in that stack is equal to the current call, and in that case your call very likely threw the last error. So based on that condition you can try to hack yourself a solution I'd never use myself.
Just wrap the args of all your return function calls with the code that you want done. So your example becomes:
foo = function(thing){do something; return(thing)}
myfunction = function() {
...
if (...) then return( foo(point 1) )
...
if (...) then return( foo(point 2) )
...
if (...) then return( foo(point 3) )
...
return ( foo(point 4) )
}
Or just make each then clause into two statements. Using on.exit to lever some code into a number of places is going to cause spooky action-at-a-distance problems and make the baby Dijkstra cry (read Dijkstra's "GOTO considered harmful" paper).
Bit more readable version of my comment on #Joris' answer:
f = function() {
ret = local({
myvar = 42
if (runif(1) < 0.5)
return(2)
stop('oh noes')
}, environment())
# code to run on success...
print(sprintf('myvar is %d', myvar))
ret
}
I guess there is not a clean way yet. I usually create an OK variable at the beginning as FALSE and turn it to TRUE at the end. I prefer on.exit over isolating all my code into a tryCatch.
myfun = function() {
OK=F # the flag "OK" will be FALSE until the function ends OK
conn = my.db.connection.function()
dbBegin(conn)
on.exit({
if(OK) dbCommit(conn) else dbRollback(conn)
dbDisconnect(conn)
})
# ... Your code. You can edit database as a transaction.
# if anything fails in R or in the database a rollback will occur
OK=T # only if the code came to the end everything went ok, so we set the flag OK as TRUE
return(NULL)
}

Resources