How to pass a function with parameters being partially fixed to a higher-order function? - functional-programming

I want to pass function ols to the higher-order function moving (or rolling) as an argument with the first argument (the dependent variable) of ols fixed. For example, I have ols([1,2], [x(n),x(n-1),x(n-2),x(n-3)])
where
the dependent variable y is fixed as [1,2]
x(n) is a vector generated from the nth rolling window over x.

In your example of partial application, the fixed input parameter is a vector. Try this script:
defg getR2(x,y){
return ols(y, x, true, 2).RegressionStat[0,1]
}
x = 1 2 3 4 5 6 7 8
y = 1 2
moving(getR2{,y},x, 2)
output:
offset 0 1 2 3 4 5 6 7
0 1 1 1 1 1 1 1
You can also fix the input parameters that are matrices in a partial application. For example:
defg getR2(x,y){
return ols(x,y,,2).RegressionStat[0,1]
}
x = matrix([1 2 3],[4,5,6])
y = matrix([1 2 3],[4,5,6])
each(def(m,n) -> moving(getR2, [m,n], 2), x, y)
output:
col1 col2
1 1
1 1

Related

Use if-else function on data frame with multiple values

I have a data frame that contains multiple values in each spot, like this:
ID<-c(1,1,1,2,2,2,2,3,3,4,4,4,5,6,6)
W<-c(29,72,32,33,34,44,42,78,32,42,18,26,10,34,39)
df1<-data.frame(ID, W)
df<-ddply(df1, .(ID), summarize,
X=paste(unique(W),collapse=","))
ID X
1 1 29,72,32
2 2 33,34,44,42
3 3 78,32
4 4 42,18,26
5 5 10
6 6 34,39
I am trying to generate another column using an if-else function so that every ID that has an X value greater than 70 will show a 1, and all others will show a 0, like this:
ID X Y
1 1 29,72,32 1
2 2 33,34,44,42 0
3 3 78,32 1
4 4 42,18,26 0
5 5 10 0
6 6 34,39 0
This is the code that I tried:
df$Y <- ifelse(df$X>=70, 1, 0)
But it doesn't work; it only seems to put the first value of each spot through the function:
ID X Y
1 1 29,72,32 0
2 2 33,34,44,42 0
3 3 78,32 1
4 4 42,18,26 0
5 5 10 0
6 6 34,39 0
It worked fine on my one column that has only one value per spot. Is there a way to get to the if-else function to evaluate every value in each spot and assign a 1 if any of them fit the statement?
Thank you, I'm sorry that I do not know a lot of R vocabulary yet.
As 'X' is a string, we can split the 'X' at the , to create a list of vectors, loop over the list with map check if there are any numeric converted values are greater than 70
library(dplyr)
library(purrr)
df %>%
mutate(Y = map_int(strsplit(X, ","), ~ +(any(as.numeric(.x) > 70))))

R Language For Loop on factorial

Sorry, i have a question on For loop.
Now there're two different loop coding, and my goal is to create a factorial via a function of for loop.
----------------------------------
Method 1
s<-function(input){
stu<-1
for(i in 1:input){
stu<-1*((1:input)[i])
}
return(stu)
}
----------------------------------------
Method 2
k <- function(input){
y <- 1
for(i in 1:input){
y <-y*((1:input)[i])
}
return(y)
}
But 1 result is
> s(1)
[1] 1
> s(4)
[1] 4
> s(8)
[1] 8
and 2 result is
> k(1)
[1] 1
> k(4)
[1] 24
> k(8)
[1] 40320
-------------------------------
It's obviously that 2 is correct, and 1 is incorrect. But why? what's different between 1 and 2? Why i can't use stu<-1*((1:input)[i]) instead of stu<-stu*((1:input)[i])?
it's because the variable stu is not updating within the for loop.
s<-function(input){
stu<-1
for(i in 1:input){
stu<-1*((1:input)[i])
message(paste(i,stu,sep="\t"))
}
return(stu)
}
s(5)
1 1 # at the first loop, 1 x 1 is calculated
2 2 # at the 2nd loop, 1 x 2 is calculated
3 3 # at the 3rd loop, 1 x 3 is calculated
4 4 # at the 4th loop, 1 x 4 is calculated
5 5 # at the 5th loop, 1 x 5 is calculated
[1] 5
However, if you use stu<-stu*((1:input)[i]) instead of stu<-1*((1:input)[i]) then the result shows following :
s(5)
1 1 # at the first loop, 1 x 1 is calculated.
2 2 # at the second loop, 1 x 2 is calculated.
3 6 # at the third loop, 2 x 3 is calculated.
4 24 # at the fourth loop, 6 x 4 is calculated.
5 120 # at the fifth loop, 24 x 5 is calculated.

for loop working outside, but not inside a function in R

I wrote this simple for loop within a function
cumulatief<- function(df){
df["cumul1"]<- 0
df$cumul1[1] = 1
y <<- 1
for (i in 2:nrow(df)) {
if (df[i,12] == df[(i-1),12]){
y <- y + 1
df$cumul1[i]<- y
} else {
df$cumul1[i] = 1
y <- 1
}
}
}
It takes a dataframe, creates a new column, and fills this column with a ranking according to the value inside another column. If it encounters a new value (which indicates a new group) it re-starts ranking from 1.
example:
12 cumul1
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
6 2 1
7 2 2
8 2 3
9 2 4
10 2 5
This is one of the first functions I wrote, and my question is:
if I just run the code without the function wrapper, it works. However, it stops working when i wrap it in a function (it creates a column full of 0, and thats it)
I have been stuck on this for half a day, any help woud be welcome!

Create a new column whose formula depends on a cell value of another row

How do I create a new column whose formula depends on a cell value of another row
x y z
1 a 1 10
2 a 2 20
3 a 3 30
4 b 1 40
This is my sample data. I want the final output to be as follows
x y z prevY
1 a 1 10 0
2 a 2 20 10
3 a 3 30 20
4 b 1 40 0
where prevY is the z value for x=current_x_val and y=current_y_val-1 0 if not available.
How do I achieve this.
My progress so far :
data[data$x == "a" & data$y==2-1,3]
I manually enter the values and get the prevY for each row. but how do i do it for all rows in a single shot ?
Or data.table solution (similar to MrFlick) but faster for a big data set
library(data.table)
setDT(dat)[, prevY := c(0, z[-length(z)]), by = x]
Here you can use the ave() function for doing group level transformations (here, a different transformation for each value of x).
dd$prevY <- with(dd, ave(z, x, FUN=function(x) head(c(0,x),-1)))
Here we take the values of z for each value of x and add a zero on the front and remove the last value. Then we assign this back to the data.frame.
This assumes that all the y values are sorted within each x group.
The result is
x y z prevY
1 a 1 10 0
2 a 2 20 10
3 a 3 30 20
4 b 1 40 0

Replace some component value in a vector with some other value

In R, in a vector, i.e. a 1-dim matrix, I would like to change components with value 3 to with value 1, and components with value 4 with value 2. How shall I do that? Thanks!
The idiomatic r way is to use [<-, in the form
x[index] <- result
If you are dealing with integers / factors or character variables, then == will work reliably for the indexing,
x <- rep(1:5,3)
x[x==3] <- 1
x[x==4] <- 2
x
## [1] 1 2 1 2 5 1 2 1 2 5 1 2 1 2 5
The car has a useful function recode (which is a wrapper for [<-), that will let you combine all the recoding in a single call
eg
library(car)
x <- rep(1:5,3)
xr <- recode(x, '3=1; 4=2')
x
## [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
xr
## [1] 1 2 1 2 5 1 2 1 2 5 1 2 1 2 5
Thanks to #joran for mentioning mapvalues from the plyr package, another wrapper for [<-
x <- rep(1:5,3)
mapvalues(x, from = c(3,1), to = c(1,2))
plyr::revalue is a wrapper for mapvalues specifically factor or character variables.

Resources