How can I set a conditional function argument value here? - r

I want to automatically set the value of an argument in a function based on another argument's value.
More specifically, I want to set a timezone value (offset) to automatically adjust time values given the region.
However, my implementation doesn't seem to work (as in the offset is never applied unless I specifically pass it as an argument to the function).
Part of the function (is supposed to) set the offset value based on region's value, and also connect to the corresponding Elasticsearch server.
This is what I have:
if (region == "EU") {
offset = "+00:00:00"
# Code to connect to EU ElasticSearch server
} else if (region == "US") {
offset = "-06:00:00"
# Code to connect to US ElasticSearch server
} else {
paste0(stop("Incorrect region supplied: ", region))
}
The function:
time_function <- function(region, retailer, start_date, end_date, offset = "+00:00:00"){
# Function body
}
(Note that I have set the default value of offset to "+00", otherwise it will throw an error that the argument is missing.)
Clearly I have gone wrong somewhere because the offset is never applied unless I explicitly specify in the argument list.
This is what I want to do:
If region == "US", then set offset to "-06:00:00",
Else if region == "EU", then set offset to "+00:00:00"
Else Error message: "supply valid region"
In short, I am looking to set a conditional argument value.
How can I achieve this?

It turns out I made an oversight in the order of assignment implementations and have just now spotted it.
For those who might be experiencing similar problems, it might be worth highlighting where I went wrong: I set the offset value after it was used, meaning that it was used/processed (using the previous iteration's value) and then it was assigned the new value.
In short, my implementation was completely correct but the order of events was incorrect.
Therefore, make sure that you set the required values before they are processed.

Your code work.
> time_function <- function(region){
+ # Function body
+ if (region == "EU") {
+ offset = "+00:00:00"
+ # Code to connect to EU ElasticSearch server
+ } else if (region == "US") {
+ offset = "-06:00:00"
+ # Code to connect to US ElasticSearch server
+ } else {
+ stop(paste0("Incorrect region supplied: ", region))
+ }
+
+ return(offset)
+ }
>
> time_function("EU")
[1] "+00:00:00"
> time_function("US")
[1] "-06:00:00"
> time_function("CH")
Error in time_function("CH") : Incorrect region supplied: CH
To optimize your code, you can use the switch.
> time_function <- function(region){
+ # Function body
+ offset <- switch(region,
+ EU = "+00:00:00",
+ US = "-06:00:00",
+ stop(paste0("Incorrect region supplied: ", region)))
+
+ return(offset)
+ }
>
> time_function("EU")
[1] "+00:00:00"
> time_function("US")
[1] "-06:00:00"
> time_function("CH")
Error in time_function("CH") : Incorrect region supplied: CH
With two parameters:
> time_function <- function(region){
+ # Function body
+ list2env(switch(region,
+ EU = list(offset = "+00:00:00", con = "EU_con"),
+ US = list(offset = "+00:00:00", con = "US_con"),
+ stop(paste0("Incorrect region supplied: ", region))), envir = environment())
+
+ return(c(offset, con))
+ }
>
> time_function("EU")
[1] "+00:00:00" "EU_con"
> time_function("US")
[1] "+00:00:00" "US_con"
> time_function("CH")
Error in list2env(switch(region, EU = list(offset = "+00:00:00", con = "EU_con"), :
Incorrect region supplied: CH

Related

Function not working as expected within code, but works perfect in console

I have R function [here is script, here is package] that works perfectly in console, but when I build and load package, something goes wrong
In console environment, I create vector, create function, assign the variable to pass to function, and output is as expected when I execute ListPalette(listname)
> PunjabiPalette <- list (
+ AmritsariKulcha = c("#e3e4d9", "#ebdc9c", "#b3340e", "#67140a", "#2a231d"),
+ CholeBhature = c("#7cab70", "#d9bf9c", "#a04d05", "#995f7e", "#972107"),
+ FieldsOfPunjab = c("#fda726", "#d75b07", "#702e06", "#514617", "#313407"),
+ FieldsOfPunjab2 = c("#9aa5b4", "#516e9c", "#13306a", "#94aa0b", "#a36316"),
+ GoldenTemple = c("#bdcad0", "#5f8abf", "#ffd860", "#d88821", "#672006"),
+ GoldenTemple2 = c("#7d84cb", "#374890","#c2592e", "#fa5102", "#722416"),
+ Pindh = c("#5eb39c", "#1f6562","#2168c2", "#d77e5f", "#5f3e25"),
+ SohniMahiwal = c("#dc6478", "#a9365a", "#f4420e", "#403c61", "#313f42"),
+ HeerRanjha = c("#93dd7d","#3272b6", "#ec9382", "#ab3a40", "#072246"),
+ Gidha = c("#fdea6e", "#4aec6a", "#fb7894", "#f13111", "#2584a0"),
+ Gidha2 = c("#fb9961", "#f13375", "#771341", "#2d3c2f", "#ea263c"),
+ Teej = c("#22325f", "#88ce64", "#fbd234", "#b8091f", "#682f4e"),
+ Phulkari = c("#efa20b", "#04a193", "#14555d","#820203", "#ed2e06"),
+ Phulkari2 = c("#9c1a41", "#42a4e8", "#3a35da", "#ee523c", "#3e167c"),
+ Jutti = c("#460809", "#00699e", "#391b72", "#03471d", "#ba0841"),
+ Jutti2 = c("#e278e5", "#13187e", "#fb6225", "#f23561", "#d2b88f"),
+ Jutti3 = c("#6fa42c", "#db3717", "#051a8d", "#ef38a7", "#202c3d"),
+ Paranda = c("#eaa32b", "#f45d59", "#c33dd2", "#92214c", "#201274")
+ )
> ListPalette <- function(listname){
+ names(listname)
+ }
> listname <- PunjabiPalette
> ListPalette(listname)
[1] "AmritsariKulcha" "CholeBhature" "FieldsOfPunjab" "FieldsOfPunjab2" "GoldenTemple" "GoldenTemple2"
[7] "Pindh" "SohniMahiwal" "HeerRanjha" "Gidha" "Gidha2" "Teej"
[13] "Phulkari" "Phulkari2" "Jutti" "Jutti2" "Jutti3" "Paranda"
>
However, when I run the same script, build the package locally and execute ListPalette(listname), I get following
> ListPalette("RanglaPunjab")
NULL
Something is amiss. I thought it might be a silly oversight, but I've been wrangling over this for more than an hour .... please guide.
Try it without quotes.
ListPalette(RanglaPunjab)
If you want to use the name of the list as a character, you must use get.
ListPalette <- function(listname){
list <- get(listname)
names(list)
}
ListPalette("PunjabiPalette")
[1] "AmritsariKulcha" "CholeBhature" "FieldsOfPunjab" "FieldsOfPunjab2" "GoldenTemple" "GoldenTemple2" "Pindh"
[8] "SohniMahiwal" "HeerRanjha" "Gidha" "Gidha2" "Teej" "Phulkari" "Phulkari2"
[15] "Jutti" "Jutti2" "Jutti3" "Paranda"

How to detect numbers from one column in another and write data from another column in R?

I'm very new at R language. I tried to make simple code to find some data in different intervals with information about start-end of interval and table with bigger intervals for now, I got several codes for solving but none of them work.
The main idea is that I have several variables which represent different arrays (i,k,j). Code, in my opinion, should look for each array in another table for two things (if it bigger than the first column and if it smaller then second, if both true - right all this to another table and go to other intervals).
if(mydatatable[k,21]>=mydatatable[i,16]){
if(mydatatable[k,21]<=mydatatable[j,18])
shifr[n,1]<-n&shifr[n,2]<-mydata[k,21]&shifr[n,3]<-mydata[k,22]&i+1&j+1&k+1&n+1
else i+1&j+1&k+1
}
else {
if(mydatatable[i,16]==0) end
else i+1&j+1&k+1
}
for this code several errors
Error in if (mydatatable[k, 21] >= mydatatable[i, 16]) { :
missing value where TRUE/FALSE needed
In addition: Warning message:
In Ops.factor(mydatatable[k, 21], mydatatable[i, 16]) :
‘>=’ not meaningful for factors
I wonder, why programm thinks, that mydatatable is factor? Why it should be some TRUE/FALSE value, I thought, that it was already established in formula.
The second code is pretty much the same and it even might work.
I preestablished the values i,k and j as 1 (i=1, k=1, j=1)
But there comes a error
> ifelse(mydatatable[k,21]>=mydatatable[i,16],
+ ifelse(mydatatable[k,21]<=mydatatable[j,18],
+ shifr[n,1]<-n&shifr[n,2]<-mydata[k,21]&shifr[n,3]<-mydata[k,22]&i+1&j+1&k+1&n+1,i+1&j+1&k+1),
+ ifelse(mydatatable[i,16]==0,
+ end),
+ i+1&j+1&k+1)
Error in ifelse(mydatatable[k, 21] >= mydatatable[i, 16], ifelse(mydatatable[k, :
unused argument (i + 1 & j + 1 & k + 1)
I'm confused, why it's happening.
Please, help.
Here is an example of data. What I want to get is demonstrated here https://1drv.ms/f/s!Aj4W4aYSeYkGiIFKHG0TV-TRQvWaIQ
Here what I got, after several use of data.table::foverlaps (I fixed some problems, but initially I got this)
> data.table::foverlaps(int1,sh2,by.x=c("start","end"),by.y=c("start","end"))
Error in data.table::foverlaps(int1, sh2, by.x = c("start", "end"), by.y = c("start", :
The first 2 columns of y's key is not identical to the columns specified in by.y.
I have also got some progress with previous code. Several problems: first, how to unite several commands (I used & and ; but none of them worked properly in shifr[n,1]<-n;shifr[n,2]<-sh[k,1];shifr[n,3]<-sh[k,1];i+1&j+?)
Second, is about Error in FUN(left, right).
> ifelse(sh[k,1]>=int[i,1],
+ + ifelse(sh[k,2]<=int[j,2],
+ + shifr[n,1]<-n;shifr[n,2]<-sh[k,1];shifr[n,3]<-sh[k,1];i+1;j+1;k+1;n+1,i+1;j+1;k+1),
Error: unexpected ';' in:
" + ifelse(sh[k,2]<=int[j,2],
+ shifr[n,1]<-n;"
> + i+1;j+1;k+1
[1] 16
[1] 16
[1] 65
> ifelse(sh[k,1]>=int[i,1],
+ + ifelse(sh[k,2]<=int[j,2],
+ + shifr[n,1]<-n;shifr[n,2]<-sh[k,1];shifr[n,3]<-sh[k,1];i+1&j+1&k+1&n+1,i+1&j+1&k+1),
Error: unexpected ';' in:
" + ifelse(sh[k,2]<=int[j,2],
+ shifr[n,1]<-n;"
> + i+1&j+1&k+1
[1] TRUE
> ifelse(sh[k,1]>=int[i,1],
+ + ifelse(sh[k,2]<=int[j,2],
+ + shifr[n,1]<-n&shifr[n,2]<-sh[k,1]&shifr[n,3]<-sh[k,1]&i+1&j+1&k+1&n+1,i+1&j+1&k+1),
+ + i+1&j+1&k+1
+ )
Error in FUN(left, right) :
operations are possible only for numeric, logical or complex types
This code is, actually, awful. I eventually done it like that(in python):
for i in interval:
...
if float(i) < intervals[b][0]:
print("Interval are too high", intervals[b][1])
break
....
if float(i) >= intervals[b - 1][1]:
....

Error from Rfacebook 'getPage' with since&until

I am using Rfacebook version 0.6.
When I call getPage with since and until dates as following, I get the following error. What I am doing wrong, or if there's something that need be updated in the package itself?
Note: <facebook_page_name>, <my_app_id>, <my_app_secret> are placeholders for illustration, without using the actual values.
Here are the details:
content<-get_fb_data("<facebook_page_name>",since="2016/01/01",until="2016/01/20",condition=2)
get_fb_data<-function(page_name,no_of_records,since_date,until_date,condition)
{
#get data from facebook page
library("Rfacebook")
fb_oauth <- fbOAuth(app_id="<my_app_id>", app_secret="<my_app_secret>",
extended_permissions = FALSE)
if (condition == 1)
{
content<-getPage(page_name, fb_oauth, no_of_records, feed = TRUE)
}
else
{
since_date<-paste(since_date,"00:00:00 IST",sep=" ")
until_date<-paste(until_date,"23:59:59 IST",sep=" ")
from_value<-as.numeric(as.POSIXct(since_date))
to_value<-as.numeric(as.POSIXct(until_date))
content<-getPage(page_name, fb_oauth,
since = from_value,
until = to_value,
feed = TRUE)
}
return(content)
}
Error displayed:
Error in as.Date.numeric(since) : 'origin' must be supplied
Per debug, this is from function as.Date called in getPage.
This should work:
library("Rfacebook")
fb_oauth <- fbOAuth(app_id="<my_app_id>", app_secret="<my_app_secret>",
extended_permissions = FALSE)
get_fb_data <- function(page_name, no_of_records, since_date,
until_date, condition){
if (condition == 1){
content<-getPage(page_name, fb_oauth, no_of_records, feed = TRUE)
} else{
content <- getPage(page_name, fb_oauth,
since = since_date,
until = until_date,
feed = TRUE)
}
content
}
content <- get_fb_data("humansofnewyork",
since_date="2016/01/01",
until_date="2016/01/2",
condition=2)
I do not really understand, why you are trying to change date format - it's unnecessary. What is more, you have a syntax error, because else should be written after } closing if. You shouldn't also load packages inside your function. What for loading it each time? The same with your fb_oauth.

R - upload current ggplot2 to imgur

The imguR package seems to be exactly what I want, but a scan of the docs makes it seem like it only uploads files. Can I upload the current plot device without outputting to a file? Specifically I'm interested in uploading plots created with ggplot2. Here is what I tried:
> token = imgur_login()
> ggplot(dstat, aes(x=obs,y=tcp)) + geom_line() + theme_bw()
> upload_image(token=token)
Error in file.exists(file) : argument "file" is missing, with no default
EDIT: I should add, I'm comfortable with a method that invisibly creates a file in the background then uploads it, this is just for quick showcasing of plots not for perfect presentation
EDIT: Here is the code I have created so far. It does not work well because there seems to be a cache used inside of account_albums that is not easily disabled. Any help finalizing this would be appreciated
get_or_create_album = function(token) {
# I can find no way to disable the cache inside
# account_albums - it always returns the first
# result unless you login again.
# So if this function creates the album, then
# the user must manually log out and log back in
# or this function will happily continue creating the album
albums = account_albums(ids=F,token=token)
albums = data.frame(t(sapply(albums,c)))
album = albums$id[albums$title == "R ggplot2"]
if (length(album) >= 1)
return(album[[1]])
album = create_album(title='R ggplot2',description='Automatic uploads from ggplot2',privacy='public', token=token)
return(album$id)
}
ggupload = function(token) {
albumID = get_or_create_album(token)
x = tempfile(fileext = '.pdf')
ggsave(filename=x)
p = last_plot()
title = ""
desc = ""
labels = names(p$labels)
if ("x" %in% labels && "y" %in% labels)
title = paste(p$labels$x,"vs",p$labels$y)
desc = title
if ("title" %in% labels)
title = p$labels$title
imgur_upload(file = x, album = albumID, title=title, description = desc, token = token)
}
This works as follows
> token = imgur_login()
> ggplot(dstat, aes(x=obs,y=tcp)) + geom_line() + theme_bw()
> ggupload(token)

Error: Attempt to apply non-function in Oracle R enterprise

I'm currently trying to implement support vector machine algorithm for classification and anomaly detection using Oracle R Enterprise (ORE). I've installed the ORE packages in RStudio
and as a sample, I'm trying to execute the following code given in Oracle Docs:
library(ORE)
m <- mtcars
m$gear <- as.factor(m$gear)
m$cyl <- as.factor(m$cyl)
m$vs <- as.factor(m$vs)
m$ID <- 1:nrow(m)
MTCARS <- ore.push(m)
And I got the following error:
Error in .ore.obj() : attempt to apply non-function
I think it is because ore.push() is not recognized but When I searched in the ORE Reference Manual it is clearly defined with an example.
So, what could be its solution?
Have you connected to your database using ore.connect?
ore.connect(user = "<userid", sid = "<sid>"
, host = "<dbserver>"
, password = "<userpwd"
, all=TRUE)
ore.connect - controls whether to automatically connect to ORE inside the closure. This is equivalent to doing an ore.connect call with the same credentials as the client session. The default value is FALSE.
ore.is.connected() ## TRUE
ore.doEval( function(){ ore.is.connected() } ) ## FALSE
ore.doEval( function(){ ore.is.connected() }, ## TRUE
ore.connect=TRUE
)
Therefore it follows this throws an error:
> ore.doEval(
+ function()
+ {
+ require(ORE)
+ ore.load("myData")
+ }
+ )
Error in .oci.GetQuery(conn, statement, data = data, prefetch = prefetch, :
ORA-20000: RQuery error
Error in OREbase:::.ore.dbGetQuery(qry) : attempt to apply non-function
ORA-06512: at "RQSYS.RQEVALIMPL", line 104
ORA-06512: at "RQSYS.RQEVALIMPL", line 101
But this is fine:
> ore.doEval(
+ function()
+ {
+ require(ORE)
+ ore.load("myData")
+ },
+ ore.connect=TRUE
+ )
[1] "FOO" "BAR"

Resources