Using user-defined for loop function to construct a data frame
There are two problems with the function:
- You're overwriting
Col_T
with allNA
s as the first statement inside the for loop. - You're returning from the function inside the for loop.
Rewrite it as follows:
myfunc <- function(X, system, Title ) {
Col_T <- data.frame(matrix(NA, ncol=length(X), nrow=4 ));
for (i in 1:4)
Col_T[i,] <- colSums(X[which(df$yr==i & df$cs==system),]);
return(Col_T);
};
User defined function input to loop every row of data frame
This is a corrected version of your program:
df <- data.frame(type=c("C", "C"), marketV=c(1.1166, 1.911), S=c(20, 60), K=c(20, 56), T=c(0.333, 0.5))
IV <- function(df) {
# check if df has more then 1 row:
if (nrow(df)>1) { message("!! nrow(df)>1 !!"); return(NA) }
# Initializing of variables
r <- 0
sigma <- 0.3
sigma_down <- 0.001
sigma_up <- 1
count <- 0
type <- df$type; marketV <- df$marketV; S <- df$S; K <- df$K; T <- df$T
d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T))
d2 <- (log(S/K) - (sigma^2/2)*T)/(sigma*sqrt(T))
if(type=="C") {
V <- exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2))
} else {
V <- exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) }
difference <- V - marketV
# Root finding of sigma by Bisection method
while(abs(difference)>0.001 && count<1000) {
if(difference < 0) {
sigma_down <- sigma
sigma <- (sigma_up + sigma)/2
} else {
sigma_up <- sigma
sigma <- (sigma_down + sigma)/2
}
d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T))
d2 <- d1 - sigma*sqrt(T)
if(type=="C") {
V <- exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2))
} else {
V <- exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) }
difference <- V - marketV
count <- count + 1
}
if(count == 1000){
return(NA) # If sigma to satisfy Black76 price cannot be found
} else{
return(sigma)
}
}
sapply(split(df, seq(nrow(df))), IV)
The main thing is to run row by row through the dataframe. This is done by
sapply(split(df, seq(nrow(df))), IV)
In your original function are many errors: the biggest is accessing to S
, K
and so on. You might thinking taking the values from the dataframe df
. But in fact you were taking the values from the workspace! I corrected this by redefining:
type <- df$type; marketV <- df$marketV; S <- df$S; K <- df$K; T <- df$T
I inserted a test for the number of rows in df
, so you will get:
> IV(df)
!! nrow(df)>1 !!
[1] NA
Here is a cleaned up version of your program:
df <- data.frame(type=c("C", "C"), marketV=c(1.1166, 1.911), S=c(20, 60), K=c(20, 56), T=c(0.333, 0.5))
IV2 <- function(type, marketV, S, K, T) {
r <- 0; sigma <- 0.3
sigma_down <- 0.001; sigma_up <- 1
count <- 0
if(type=="C") {
f.sig <- function(sigma) {
d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T))
d2 <- d1 - sigma*sqrt(T)
exp(-r*T)*(S*pnorm(d1) - K*pnorm(d2)) - marketV
}
} else {
f.sig <- function(sigma) {
d1 <- (log(S/K) + (sigma^2/2)*T)/(sigma*sqrt(T))
d2 <- d1 - sigma*sqrt(T)
exp(-r*T)*(K*pnorm(-d2) - S*pnorm(-d1)) - marketV
}
}
ifelse(f.sig(sigma_down)*f.sig(sigma_up) < 0, uniroot(f.sig, c(sigma_down,sigma_up))$root, NA) # sigma
}
sapply(split(df, seq(nrow(df))), do.call, what="IV2")
How to use for loop to create new data frames using i in the name of data frame in R
You can try :
library(dplyr)
yearlist <- c(2013, 2014)
lapply(yearlist, function(x) {
maxyear <- x
minyear <- maxyear - 7
mutatedata %>%
filter(year>=minyear & year<=maxyear) %>%
group_by(symbol) %>%
summarize(
avgroepercent = mean(roe,na.rm = TRUE),
avgrocpercent = mean(roc, na.rm = TRUE),
epsroc = (((last(eps))/(first(eps)))^(1/(maxyear-minyear))-1)
)
}) -> data
where data
is a list of dataframes. If you want to create separate dataframes you can use list2env
.
names(data) <- paste0('metrics_', yearlist)
list2env(data, .GlobalEnv)
Applying For loop with def function to generate other DataFrame?
Yes you could just do:
for item in medal['event_gender'].unique():
globals()[item] = gender(medal, item)
But why do this? Maintain your dataframe as it is and work on it with groupings. It is easier that way to do same computations on different groups of the same dataframe rather than doing same computation on different dataframes
User defined function within for-loops
If I understood your question properly, then you need to assign the results in your last 'for' loop:
for(i in 1:num_students){
if(i == 1) out <- NULL
out <- c(out, emotion_difference_fun(probs))
}
out
Is that what you are looking for?
What I am unclear about though, is why in your second code section you are not looking for a 5*5 matrix. Eventually, when running that code, it doesn't matter that you did it for i = 5 students, because it will only save in row_prob your last iteration (student = 5).
Using a for loop to apply a function to a list in R
The df
doesn't update the original object 'df1', 'df2' in the global env. If we want, use assign
(or better is to keep it in a list
)
# // create a named `list`
dataframes = list(df1,df2,df3,df4)
names(dataframes) <- c("df1", "df2", "df3", "df4")
# // loop over the names of the list
for(nm in names(dataframes)) {
# // get the value of the object from the names
df <- get(nm)
# // create the new columns
df[paste0("lag", 1:12)] <- lapply(1:12, lag, x=df[,2])
df[paste0("lead", 1:12)] <- lapply(1:12, lead, x=df[,2])
# // assign to update the original object
assign(nm, df)
}
It may be better to keep it in a list
dataframes2 <- lapply(dataframes, function(df) {
df[paste0("lag", 1:12)] <- lapply(1:12, lag, x=df[,2])
df[paste0("lead", 1:12)] <- lapply(1:12, lead, x=df[,2])
df
})
The list
output can be used to update the original objects with list2env
though not recommended
list2env(dataframe2, .GlobalEnv)
How to loop/map a function over a data frame with the output named according to the input variables?
You can pass column names as string.
library(dplyr)
library(purrr)
library(rlang)
tbl_loadings <- function(data, depen_indepen_vars, pcs ) {
dep <- sym(depen_indepen_vars)
pcs <- sym(pcs)
loadX <- data %>%
filter(!!pcs != "NA") %>%
mutate(load = paste0(!!dep, " (", !!pcs, "), ", collapse = "")) %>%
pull(load) %>% unique()
return(loadX)
}
map(paste0('X', 1:3), tbl_loadings, data = loadings, depen_indepen_vars = "Met")
#[[1]]
#[1] "Met1 (0.5), Met2 (0.1), "
#[[2]]
#[1] "Met1 (0.1), Met3 (0.8), "
#[[3]]
#[1] "Met1 (0.3), Met2 (0.9), "
R: build data frame in user defined function
rbind
ing data.frames
is very slow in my experience, but anyway: replace your placeholder with return(data.frame(x,calc))
.
After changing the function, probably the easiest way to get them all into one data.fame
is through:
output<-do.call(rbind, lapply(letters, functest))
applying a user defined function to a dataframe
A simple fix would be:
for group in Final.groupby('Key'):
# group is a tuple where the first value is the Key and the second is the dataframe
result = regression(group[1])
# do xyz with result
EDIT:
you do not have to convert group into a data frame again and can use it directly as it is already in the proper format.
# this line is not necessary
Final1 = pd.DataFrame(Final1)
judging from the error it is clear that the group
that you have passed into the train_test_split function does not have enough records. which is quite evident in the error message. you will have to handle for such errors using try, except.
Related Topics
General Guide for Creating Publication Quality Tables Using R, Sweave, and Latex
How to Print (To Paper) a Nicely-Formatted Data Frame
Can Not Connect Postgresql(Over Ssl) with Rpostgresql on Windows
Principal Components Analysis - How to Get the Contribution (%) of Each Parameter to a Prin.Comp
Higher Level Functions in R - Is There an Official Compose Operator or Curry Function
Convergence Error for Development Version of Lme4
Graph Flow Chart of Transition from States
Annotate Ggplot2 Facets with Number of Observations Per Facet
Embedding Googlevis Charts into a Web Site
Dplyr::Select() with Some Variables That May Not Exist in the Data Frame
How to Select Rows According to Column Value Conditions
Loess Fit and Resulting Equation
Tidyr::Pivot_Wider() Reorder Column Names Grouping by 'Name_From'