I want to calculate the loan outstanding at valuation date for a data set. I define a function but when I call the function its giving an error saying the fifth argument is missing(term).
Function is as follows:
loan_outstanding<-function(c_date,v_date,l_amt,int ,pmt,term){
l_amt<-as.numeric(l_amt)
freq<-12
term_in_months<-as.numeric(term)*freq
c_date<-as.Date(c_date,"%d/%m/%Y")
Interest_Rate<-per_to_num(int)
v_date<-as.Date(v_date,"%Y-%m-%d")
date_<-numeric(500)
date_[1]<-as.character(c_date)
int_cal<-numeric(500)
cap_repay<-numeric(500)
loan_out<-numeric(500)
loan_out[1]<-l_amt
i<-2
while(as.Date(date_[i-1],"%Y-%m-%d")<v_date){
date_[i]<-as.character(AddMonths(as.Date(date_[i-1],"%Y-%m-%d"),1),"%Y-%m-%d")
int_cal[i]<-loan_out[i-1]*((1+Interest_Rate)^(1/freq)-1)
cap_repay[i]<-pmt-int_cal[i]
loan_out[i]<-max(loan_out[i-1]-cap_repay[i],0)
i<-i+1
}
val<- loan_out[i-2]
return(val)
}
The error :
>loan_outstanding("28/07/2011","2017-03-31",500000,7,9629.918)
argument "term" is missing, with no default
Is there a mistake in my code?
This is not a pretty solution, but I just made another variable and put it after the last one in the function definition:
...pmt, term, [new var]) {
It solved the problem for me.
Related
I would like to pass function arguments to R glm model objects. However, it seems my code below didnot work as R didn't recognize the passing argument.
I kept getting the error: non-numeric argument to binary operator
grid = (cbind(c('wl', 'livingd', 'deceasedt'), c('wl_time', 'ld_time', 'dec_time')))
for (k in 1:nrow(grid)){
f=function(y=as.name(grid[k,1]), offset=as.name(grid[k,2])){
m=glm(y~chain_class2+sex_new+age_cat+race_new,
family=poisson(link='log'),
data=poissonset,
offset=log(offset/12))
}
}
Is there a way to pass the variable names to the function? Thank you!
Try this:
grid = (cbind(c('wl', 'livingd', 'deceasedt'), c('wl_time', 'ld_time', 'dec_time')))
for (k in 1:nrow(grid)){
f=function(y=as.name(grid[k,1]), offset=as.name(grid[k,2])){
m=glm(get(y)~chain_class2+sex_new+age_cat+race_new,
family=poisson(link='log'),
data=poissonset,
offset=log(get(offset)/12))
}
}
I am trying to create a function which will look at two vectors of character labels, and print the appropriate label based on an If statement. I am running into an issue when one of the vectors is populated by NA.
I'll truncate my function:
eventTypepriority=function(a,b) {
if(is.na(a)) {print(b)}
if(is.na(b)) {print(a)}
if(a=="BW"& b=="BW",) {print("BW")}
if(a=="?BW"& b=="BW") {print("?BW")}
...#and so on
}
Some data:
a=c("Pm", "BW", "?BW")
b=c("PmDP","?BW",NA)
c=mapply(eventTypepriority, a,b, USE.NAMES = TRUE)
The function works fine for the first two, selecting the label I've designated in my if statements. However, when it gets to the third pair I receive this error:
Error in if (a == "?BW" & b == "BW") { :
missing value where TRUE/FALSE needed
I'm guessing this is because at that place, b=NA, and this is the first if statement, outside of the 'is.na' statements, that need it to ignore missing values.
Is there a way to handle this? I'd really rather not add conditional statements for every label and NA. I've also tried:
-is.null (same error message)
-Regular Expressions:
if(a==grepl([:print:]) & b==NA) {print(a)}
In various formats, including if(a==grepl(:print:)... No avail. I receive an 'Error: unexpected '[' or whatever character R didn't like first to tell me this is wrong.
All comments and thoughts would be appreciated. ^_^
if all your if conditions are exclusives, just call return() to avoid checking other conditions when one is met:
eventTypepriority=function(a,b) {
if(is.na(a)) {print(b);return()}
if(is.na(b)) {print(a);return()}
if(a=="BW"& b=="BW",) {print("BW");return()}
if(a=="?BW"& b=="BW") {print("?BW");return()}
...#and so on
}
You need to use if .. else statements instead of simply if; otherwise, your function will evaluate the 3rd and 4th lines even when one of the values is n/a.
Given you mapply statement, I also assume you want the function to output the corresponding label, not just print it?
In that case
eventTypepriority<-function(a,b) {
if(is.na(a)) b
else if(is.na(b)) a
else if(a=="BW"& b=="BW") "BW"
else if(a=="?BW"& b=="BW") "?BW"
else "..."
}
a=c("Pm", "BW", "?BW")
b=c("PmDP","?BW",NA)
c=mapply(eventTypepriority, a,b, USE.NAMES = T)
c
returns
Pm BW ?BW
"..." "..." "?BW"
If you actually want to just print the label and have your function return something else, you should be able to figure it out from here.
I am trying to delete all values in a list that have the tag ".dsw". My list is a list of files using the function list.files. This is my code:
for (file in GRef) {
if (strsplit(file, "[.]")[[1]][3] == "dsw") {
#GRef=GRef[-file]
for(n in 1:length(GRef)){
if (GRef[n] == file){
GRef=GRef[-n]
}
}
}
}
Where GRef is the list of file names. I get the error listed above, but I dont understand why. I have looked at this post: Error .. missing value where TRUE/FALSE needed, but I dont think it is the same thing.
You shouldn't attempt to to modify a vector while you are looping over it. The problem is your are removing items you are then trying to extract later which is causing the missing values. It's better to identify all the items you want remove first, then remove them. For example
GRef <- c("a.file.dsw", "b.file.txt", "c.file.gif", "d.file.dsw")
exts <- sapply(strsplit(GRef, "[.]"), `[`, 3)
GRef <- GRef[exts!="dsw"]
I'm making a function and before it does any of the hard stuff I need it to check that all the column names listed in the 'samples' dataset are also present in the 'grids' dataset (the function maps one onto the other).
all(names(samples[expvar]) %in% names(grids))
This does that: the code within all() asks if all the names in the list ('expvar') of columns in 'samples' are also names in 'grids'. The output for a correct length=3, expvar would be TRUE TRUE TRUE. 'all' asks if all are TRUE, so the output here is TRUE. I want to make an IF statement along the lines of:
if(all(names(samples[expvar]) %in% names(grids)) = FALSE) {stop("Not all expvar column names found as column names in grids")}
No else needed, it'll just carry on. The problem is that the '= FALSE' is redundant because all() is a logically evaluable statement... is there a "carry on" function, e.g.
if(all(etc)) CARRYON else {stop("warning")}
Or, can anyone think of a way I can restructure this to make it work?
You're looking for the function stopifnot.
However you don't need to implement it as
if (okay) {
# do stuff
} else {
stop()
}
which is what you have. Instead you can do
if (!okay) {
stop()
}
# do stuff
since the lines will execute in sequential order. But, again, it might be more readable to use stopifnot, as in:
stopifnot(okay)
# do stuff
I would code it:
if(!all(...))
stop(...)
... rest of program ...
I want to document a replacement function in R, but when I run R CMD check I get this error message:
Bad \usage lines found in documentation object 'timestamps':
<unescaped bksl>S4method{"timestamps<-"}{.MoveTrack}(this, value)
Functions with \usage entries need to have the appropriate \alias
entries, and all their arguments documented.
The \usage entries must correspond to syntactically valid R code.
the documentation looks like this:
\name{timestamps}
\alias{timestamps}
\alias{timestamps,.MoveTrack-method}
\alias{timestamps,.MoveTrackSingle-method}
\alias{"timestamps<-",.MoveTrack-method}
\docType{methods}
\title{Extract the timestamps of a Move or MoveStack object}
\description{The timestmaps method returns or sets the timestamps of a track from a Move or MovesStack object.}
\usage{
\S4method{timestamps}{.MoveTrackSingle}(this)
\S4method{timestamps}{.MoveTrack}(this)
\S4method{"timestamps<-"}{.MoveTrack}(this, value)
}
\arguments{
\item{this}{Move or MoveStack object}
\item{value}{timestamps from class POSIXct}
}
and the actual function is the following:
setGeneric("timestamps", function(this) standardGeneric("timestamps"))
setMethod("timestamps", ".MoveTrack",
function(this) {
this#timestamps
})
setMethod("timestamps", ".MoveTrackSingle",
function(this) {
this#timestamps
})
setGeneric("timestamps<-", function(this, value) standardGeneric("timestamps<-"))
setReplaceMethod("timestamps", ".MoveTrack",
function(this, value) {
this#timestamps <- value
this
})
I searched for the error message but all I found was about Roxygen documentation which didn't help me. I also tried different documentation styles like :
\S4method{"timestamps<-"}{.MoveTrack}(this, value)
\S4method{"timestamps<-."}{.MoveTrack}(this, value)
\S4method{"timestamps<-$"}{.MoveTrack}(this, value)
\S4method{'timestamps<-'}{.MoveTrack}(this, value)
\S4method{timestamps<-}{.MoveTrack}(this, value)
\S4method{"timestamps\<\-"}{.MoveTrack}(this, value)
\S4method{"timestamps\\<\\-"}{.MoveTrack}(this, value)
but non of them worked. Any idea?
Thanks a lot in advance.
best, marco
Try
\S4method{timestamps}{.MoveTrack}(this) <- value
with multiple dispatch in the second{} as a comma-separate list.