Error when running initPortf in Blotter package for R - r

I am having trouble initializing portfolios with the Blotter Package in R.
I am cycling through a list of variables that I want to initialize, and when I initialize with a single symbol, it works fine.
But when I try to do it with a list of symbols, it throws up the error:
Error in portfolio$symbols[[instrument]] <- new.env(hash = TRUE) :
wrong arguments for environment subassignment
Here is my code:
for (i in strategies) {
temp_symbol_list <- as.list(c(portfolio_txns %>%
filter(strategy == i) %>%
select(symbol)))
# temp_symbol_list <- as.list(temp_symbol_list)
print (i)
print (temp_symbol_list)
initPortf(i, temp_symbol_list,initDate = earliest_date, currency = "CAD")
}
When there is only one symbol in the intialize function, it works fine. But if there are two symbols, I get the error.
I have tried many different ways of creating the symbol list, but I think it is expecting something that I am not able to create.
For example, if I do the following:
initPortf("strategy",c("symbol 1","symbol 2"), initDate = earliest_date,
currency = "CAD")
it works fine.
Somehow, my list is the problem.

I figured it out.
I was created the variable to send to the initPortf as a "list". I changed it to a string and it worked.
Specifically, this is the new line
temp_symbol_list <- toString(temp_symbol_list)
I was confused as the documentation for the Blotter package said it was expecting a list, but I probably don't understand the different types of data storage properly.
I'm leaving this up in case someone else has the same problem.
Big thanks to the folks who wrote these packages btw.

Related

Create CYT object in CytoTree in R

I want to create a CytoTree CYT object in R to analyse my .FCS files. When I am using the Quick start code in the package description, I will always get an error when running the createCYT() function that says:
Error in createCYT(raw.data = fcs.data, normalization.method = "log") :
2022-09-26 15:46:26 meta.data must be a data.frame
As the function should not rely on any meta data and that object is optional, I do not know how to solve the error.
Here is the description:
https://ytdai.github.io/CytoTree/quick-start.html#quick-start-code
I thank you very much in advance for your help!
BR
I have encountered same problem previously.
In the end it worked only when the data.frame was added (yes, even though it should not depend on it).
Here is how:
meta.data <- data.frame(cell = rownames(fcs.data), stage = gsub(".fcs.+", "", rownames(fcs.data)))
meta.data$stage <- factor(as.character(meta.data$stage))
You may as well have a look at the Cytotree PDF in case of more issues.

Issue with summary() function in R

I am new to programming and trying to learn R using swirl.
In one of the exercises I was told to use the summary function on a dataset. However I encountered a discrepancy in the way the summary was printed:
Instead of summarizing the categorical variable values, it instead says something about length, class and mode.
I went around searching for why this might be happening to no avail, but I did manage to find what the output is supposed to look like:
Any help would be greatly appreciated!
This behaviour is due to the option stringsAsFactors, which is FALSE by default on R 4. Previously it was TRUE by default:
From R 4 news: "now uses a `stringsAsFactors = FALSE' default, and hence by default no longer converts strings to factors in calls to data.frame() and read.table()."
A way to return to the previous behaviour with the same code is to run options(stringsAsFactors=T) before building dataframes. However, there is a warning saying this option will eventually be removed, as explained here.
For your new code, you can use the stringsAsFactors parameter, for instance data.frame(..., stringsAsFactors=T).
If you already have dataframes and you want to convert them, you could use this function to convert all character variables (you will have to adapt if only some variables need conversion):
to.factors <- function(df) {
i <- sapply(df, is.character)
df[i] <- lapply(df[i], as.factor)
df
}

R: Creating a custom error message giving argument values for a function in a package

Suppose there is a set of functions, drawn from a package not written by me, that I want to assign to a special behavior on error. My current concern is with the _impl family of functions in dplyr. Take mutate_impl, for example. When I get an error from mutate, traceback almost always leads me to mutate_impl, but it is usually a ways up the call stack -- I have seen it be as many as 15 calls from the call to mutate. So what I want to know at that point is typically how the arguments to mutate_impl relate to the arguments I originally supplied to mutate (or think I did).
So, this code is probably wrong in too many ways to count -- certainly it does not work -- but I hope it at least helps to express my intent. The idea is that I could wrap it around mutate_impl, and if it produces an error, it saves the error message and a description of the arguments and returns them as a list
str_impl <- function(f){tryCatch(f, error = function(c) {
msg <- conditionMessage(c)
args <- capture.output(str(as.list(match.call(call(f)))))
list(message = msg, arguments = args)
}
assign(str_impl(mutate_impl), .GlobalEnv)
Although, this still falls short of what I really want, because even without the constraint of working code, I could not figure out how to produce a draft. What I really want is to be able to identify a function or list of functions that I want to have this behavior on error, and then have it occur on error whenever and wherever that function is called. I could not think of any way to even start to do that without rewriting functions in the dplyr package environment, which struck me as a really bad idea.
The final assignment to the global environment is supposed to get the error object back to somewhere I can find it, even if the call to mutate_impl happens somewhere inaccessible, like in an environment that ceases to exist after the error.
Probably the best way of achieving what you want is via the trace functionality. It's surely worth reading the help about trace, but here is a working example:
library(dplyr)
trace("mutate_impl", exit = quote({
if (class(returnValue())[1]=="NULL") {
cat("df\n")
print(head(df))
cat("\n\ndots\n")
print(dots)
} else {
# no problem, nothing to do
}
}), where = mutate, print = FALSE)
# ok
xx <- mtcars %>% mutate(gear = gear * 2)
# not ok, extra output
xx <- mtcars %>% mutate(gear = hi * 2)
It should be fairly simple to adjust this to your specific needs, e.g. if you want to log to a file instead:
trace("mutate_impl", exit = quote({
if (class(returnValue())[1]=="NULL") {
sink("error.log")
cat("df\n")
print(head(df))
cat("\n\ndots\n")
print(dots)
sink()
} else {
# no problem, nothing to do
}
}), where = mutate, print = FALSE)

Importing a file only if it has been modified since last import and then save to a new object

I am trying to create a script that I run about once a week. The goal is that it will go out and check an MS Excel file that a co-worker manages. It then tests to see if the date the file was modified is newer then the last time it was imported. If it is newer, it will import the file (I am using readxl package - WONDERFUL!) into a new object that is a named with the date the original Excel file was last modified included in the object name. I have everything working except for the assignment of the imported data.frame to a new object that includes the date.
An example of the code I am using is:
First I create an object with a path pointing to the file of interest.
pfdFilePath <- file.path("H:", "3700", "3780", "002-00", "3.
Project Information", "Program", "RAH program.xls")
after testing to verify the file has been modified, I have tried simple assignment ("test" is just an example for simplification):
paste("df-", as.Date(file.info(pfdFilePath)$mtime), sep = "") <- "test"
But that code produces an error:
Error in paste("df-", as.Date(file.info(pfdFilePath)$mtime), sep = "") <- "test" :
target of assignment expands to non-language object
I then try the assign function:
assign(paste("df-", as.Date(file.info(pfdFilePath)$mtime), sep = ""), "test")
Running this code creates an object that looks to be okay, but when I evaluate it, or try using str() or class() I get the following error:
Error in df - df-2016-08-09 :
non-numeric argument to binary operator
I am pretty sure this is an error that has to do with the environment I am using assign, but being relatively new to R, I cannot figure it out. I understand that the assign function seems to be frowned upon, but those warnings seem to centered on for-loops vs. lapply functions. I am not really iterating within a function though. Just a dynamically named object whenever I run a script. I can't come up with a better way to do it. If there is another way to do this that doesn't require the assign function, or a better way to use assign function , I would love to know it.
Thank you in advance, and sorry if this is a duplicate. I have spent the entire evening digging and can't derive what I need.
Abdou provided the key.
assign(paste0("df.", "pfd.", strftime(file.info(pfdFilePath)$mtime, "%Y%m%d")), "test01")
I also converted to the cleaner paste0 function and got rid of the dashes to avoid confusion. Lesson learned.
Works perfectly.

R 'object XX not found' error thrown inside function, but not in script

I am fairly new to R, so my apologies if this question is a bit silly.
I am calling a function in an external package ('mmlcr', although I don't think that is directly relevant to my problem), and one of the required inputs (data) is a data.frame. I compose the data.frame from various data using the following approach (simplified for illustration):
#id, Time, and value are vectors created elsewhere in the code.
myData = data.frame(a=id, b=Time, c=value)
out <- mmlcr( input1, input2, data=myData, input4)
Which throws the error:
Error in is.data.frame(data) : object 'myData' not found
The debugger indicates that this error is thrown during the mmlcr() call.
I then added a print(ls()) immediately prior to the mmlcr() call, and the output confirmed that "myData" was in my function workspace; further is.data.frame(myData) returned TRUE. So it seems that "myData" is successfully being created, but for some reason it is not passing into the mmlcr() function properly. (Commenting this line causes no error to be thrown, so I'm pretty sure this is the problematic line).
However, when I put the exact same code in a script (i.e., not within a function block), no such error is thrown and the output is as expected. Thus, I assume there is some scoping issue that arises.
I have tried both assignment approaches:
myData = data.frame(a=id, b=Time, c=value)
myData <- data.frame(a=id, b=Time, c=value)
and both give me the same error. I admit that I don't fully understand the scope model in R (I've read about the differences between = and <- and I think I get it, but I'm not sure).
Any advice you can offer would be appreciated.
MMLCR is now deprecated and you should search for some alternatives. Without looking too much into it, I sleuthed through an old repo and found the culprit:
m <- eval(m, data)
in the function mmlcr.default. There are a lot of reasons why this is bad, but scoping is the big one. R has this issue with the subset.data.frame function, see my old SO question. Rather than modify the source code, I would find a way to do your function with a subroutine using a for, repeat, or while loop.

Resources