In R I have a function "getHbasedPortfolio". The body of the function is as follows:
body("getHbasedPortfolio")
{
className <- name
pf = list(name = name,
get = function(x) pf[[x]],
set = function(x,value) pf[[x]] <- value
)
pf$getCash = function(date) {
data <-data.frame(name=name,value="null")
return(data)
}
pf$setCash = function(cash, date) {
a <- insertCashTable(pf$name, cash, date)
return("success")
}
pf <- list2env(pf)
class(pf) <- name
return(pf)
}
I need to separate each lines with commas. So I wrote a code to do that.
The code I used is as follows:
body <-"";
for(i in 1:length(as.character(body("getHbasedPortfolio")))){
body <- paste(body,as.character(body("getHbasedPortfolio"))[i])
body <- paste(body,";")
}
Now I am getting the following output.
body
[1] " { ; className <- name ; pf = list(name = name, get = function(x) pf[[x]], set = function(x, value) pf[[x]] <- value) ; pf$getCash = function(date) {\n data <- data.frame(name = name, value = \"null\")\n return(data)\n} ; pf$setCash = function(cash, date) {\n a <- insertCashTable(pf$name, cash, date)\n return(\"success\")\n} ; pf <- list2env(pf) ; class(pf) <- name ; return(pf) ;"
The problem is that the statements under the pf$setCash and pf$getCash are not separated by commas.
How can I overcome this problem?
You can use something like this:
dat <- data.frame(capture.output(getHbasedPortfolio))
This will save your function line by a line in a data.frame. You can then save it in your data base.
EDIT
you can use dat to write line by line.
paste(data.frame(capture.output(getHbasedPortfolio))[,1],
collapse=',') ## I would use another separator here becuase comma is confusing
Related
How do I pass an array into the query of httr?
The request url should look like that:
https://www.example.com/xyz?type=3&type=5
My current code looks like that:
POST(url,
query = data.frame("something" = "somethingElse", type = ),
add_headers(.headers = c("token" = token),
encode = "json")
How do I add those types from the url example to my R example?
The default encoding for httr doesn't like to use the same name multiple times, but it is possible to separate your values into lists which have duplicate names. Here's a helper function i've used that can help
flattenbody <- function(x) {
# A form/query can only have one value per name, so take
# any values that contain vectors length >1 and
# split them up
# list(x=1:2, y="a") becomes list(x=1, x=2, y="a")
if (all(lengths(x)<=1)) return(x);
do.call("c", mapply(function(name, val) {
if (length(val)==1 || any(c("form_file", "form_data") %in% class(val))) {
x <- list(val)
names(x) <- name
x
} else {
x <- as.list(val)
names(x) <- rep(name, length(val))
x
}
}, names(x), x, USE.NAMES = FALSE, SIMPLIFY = FALSE))
}
Then you could use it with something like
POST(url,
query = flattenbody(list(something="somethingElse", type = c(3, 5))),
add_headers(.headers = c("token" = token)),
encode = "json"
)
I don't understand why this process that works outside the function doesn't work inside the function
First some data:
add.variable.to.list <- function () {
data <- dplyr::lst(!! variableName := dplyr::lst(ICD10, ICD8, ATC))
VariableDefinor <- append(VariableDefinor, data)
return(VariableDefinor)
}
# Initiate variable super list
#smoking marker
ICD10 <- paste("^", c("DF17", "DZ720", paste("DJ", seq(40,44,1), sep = ""), "D716"), sep ="")
ICD8 <- c()
ATC <- c("^R03", "^N07BA")
variableName <- c("smokingMarker")
VariableDefinor <- dplyr::lst(!! variableName := dplyr::lst(ICD10, ICD8, ATC))
#obesity
ICD10 <- paste("^D", c("E65", "E66", "E68", "E68"), sep = "")
ICD8 = c()
ATC = c()
variableName <- c("obesity")
VariableDefinor <- add.variable.to.list()
What I want to put in a function:
unlist(flatten(VariableDefinor$obesity))
This outputs: "^DE65" "^DE66" "^DE68" "^DE68"
My best version of a function that would allow me to do this in a general manner:
variable.selector <- function (variableList, variableName) {
unlist(flatten(variableList$variableName)) #combines sublists to single character vector
}
variable.selector(variableList = VariableDefinor, variableName = "obesity")
Please I would greatly appreciate beyond help with this, if you can point out what it is that I don't understand so I can do it myself next time!
I wish to write a function to analyze several identical variables in several datasets
I built the function below but it does not work well. I am not sure how to pass a name in a function dynamically. Could someone help?
There are 10 identical variables (testvar1, testvar2,..., testvar10, etc...)
in 15 different datasets (mydata1, mydata2,...mydata15, etc...)
library(readxl)
to_analyze <- function (data="mydata1", var = testvar1) {
#reading my file in
excelfile <- paste(`data`, "xlsx", sep = ".")
dataset_name <- read_excel(excelfile)
#populating the testvar1, testvar2,...
dataset_name$var_interest <- dataset_name$var #this does not work
#I was hoping it would give dataset_name$var_interest <- dataset_name$testvar1
#creating a smaller dataset
eco <- dataset_name %>%
select(id, var_interest) #I want var_interest to be testvar1 (not the value but the name)
##doing some analysis on that dataset
}
#creating another function for all the datasets (15 total)
fct_all <- function(x){
for(i in 1:15){
iq <- as.double(i)
dsn <- paste("mydata", deparse(iq), sep="")
to_analyze(data=dsn, var = x)
}
}
#applying the function for all the variables
all_var <- c(testvar1, testvar2, testvar3)
fct_all(all_var)```
You can use equivalently data$var1 or data[['var1']]. Which means that with the second form, as you provide the variable name as a string, you can easily replace the string by a dynamical variable name :
var <- 'var1'
dataset_name$var_interest <- dataset_name[[var]]
Note that dplyr is very clever and does accept string or symbols. Which means you can further simplify your function with one of the following forms :
library(dplyr)
# Using select then rename with the var given as a string
to_analyze <- function (data = "mydata1", var = "testvar1") {
eco <- paste(data, "xlsx", sep = ".") %>%
read_excel() %>%
select(id, var) %>%
rename(var_intereset = var)
...
}
For the sake of interest, you could also use quasiquotation, but given that you'll eventually wrap your variables into a vector, I guess it's not that useful. Would be something of the form :
library(dplyr)
to_analyze <- function (data = "mydata1", var = quo(testvar1)){
quo_var <- enquo(var)
eco <- paste(data, "xlsx", sep = ".") %>%
read_excel() %>%
select(id, !!quo_var) %>%
rename(var_intereset = !!quo_var)
...
}
This form allows you to call your variable with the raw variable name rather than a string : to_analyse(data = "mydata1", var = testvar1). But as said before, probably not the most useful in your case.
Thank you #Romain. Your code worked well. I just changed the single quote to backticks
var <- `var`
to_analyze <- function (data = "mydata1", var = "testvar1") {
eco <- paste(data, "xlsx", sep = ".") %>%
read_excel() %>%
select(id, var) %>%
rename(var_intereset = var)
...
}
I have the following data table and function which extracts a parameter and adds it as a column to a data table:
library(stringr)
library(data.table)
pq <- c("cm_mmc=MSN-_-Exact-_-BrandExact-_-CheddarCheese"
,"cm_mmc=Google-_-cheeseTypes-_-cheddar-_-cheesedelivered&gclid=CMXyy2D81MsCFcsW0w0dMVoPGw"
,"cm_mmc=MSN-_-worldcitiesuslocations-_-cheese-_-cheeseshops"
,"cm_mmc=MSN-_-worldcitiesuslocations-_-cheese-_-cheeseshops")
rq <- c("q=cheese&src=IE-SearchBox&FORM=IESR02",
"sa=L",
"q=london+cheese+shop&src=IE-TopResult&FORM=IETR02&pc=WCUG",
"q=london+cheese+shop&src=IE-TopResult&FORM=IETR02&pc=WCUG")
DT = data.table(page_urlquery = pq, refr_urlquery = rq)
# Extracts a paramater from the relevant query and adds it to the table as a column
extract_param <- function(dt, source = c("page_urlquery", "refr_urlquery"), param_name){
source <- match.arg(source)
regexp <- paste("(?i)", param_name, "=([^&]+)", sep="")
col_name <- switch(source
,"page_urlquery" = paste("url_", param_name, sep = "")
,"refr_urlquery" = paste("ref_", param_name, sep = "")
)
dt[,(col_name):= str_match((source), regexp)[,2]]
}
However when I call the function as follows:
extract_param(DT, "page_urlquery", "cm_mmc")
It creates the column, but the contents are blank. I think it's something wrong with the syntax in the data table (source) parameter. What am I missing?
change the code inside function from
dt[,(col_name):= str_match((source), regexp)[,2]]
to
dt[,(col_name):= str_match(get(source), regexp)[,2]]
In the code below, the dataframe offshore_Sites already exists and contains at about 1000 records. I am building a function so I can re-use it for all the other dataframes I have.
The dataframes are obtained from SQL Server. At the moment I have only got the offshore_Sites one but the others will be produced in the same way.
The idea is to call this function, that has a switch statement inside and, depending on the dataframe, I will be performing different transformations. For the offshore_Sites one, I need to concatenate some of the fields, as in the example.
myStringConn <- "Driver=SQL Server;Server=SQL-SPATIAL;Database=AreasProt;Trusted_Connection=True;"
conn <- odbcDriverConnect(myStringConn)
offshore_Sites <- sqlQuery(conn, "select * from Offshore_Sites")
formatDataFrame <- function(dataframe) {
switch(dataframe, "offshore_Sites" = {
offshore_sites <- as.data.table(offshore_Sites)
offshore_sites <- setnames(offshore_sites, 1:6, c("status","country","region","area","long","lat"))
offshore_sites <- unique(offshore_sites[, list(status,
country = paste(sort(unique(country)), collapse = ' & '),
region = paste(sort(unique(region)), collapse = ' & '),
area,
long,
lat), by = code])
})
}
formatDataFrame(offshore_Sites)
However, when I run this, I get the error:
Error in switch(dataframe, offshore_Sites = { :
EXPR must be a length 1 vector
Does anyone understand what is happening?
I had some inspiration today and I kind of spotted where the problem was. The function needs two variables, the dataframe name and the dataframe itself.
myStringConn <- "Driver=SQL Server;Server=SQL-SPATIAL;Database=AreasProt;Trusted_Connection=True;"
conn <- odbcDriverConnect(myStringConn)
offshore_Sites <- sqlQuery(conn, "select * from Offshore_Sites")
formatDataFrame <- function(dataframe, dataframeName) {
switch(dataframeName, "offshore_Sites" = {
offshore_sites <- as.data.table(dataframe)
offshore_sites <- setnames(offshore_sites, 1:6, c("status","country","region","area","long","lat"))
offshore_sites <- unique(offshore_sites[, list(status,
country = paste(sort(unique(country)), collapse = ' & '),
region = paste(sort(unique(region)), collapse = ' & '),
area,
long,
lat), by = code])
})
}
formatDataFrame(offshore_Sites, "Offshore_Sites")
Thanks for all the comments :)