I have a for loop that returns the slope of a best-fit fine over three consecutive data points.
My data:
dput(DIP)
structure(list(DSI = c(4, 6, 8, 10, 12, 14, 16, 18, 20, 22),
Flask1 = c(0.062, 0.117, 0.33, 0.617, 1.194, 1.855, 1.706,
1.537, 1.453, 1.467), Flask2 = c(0.045, 0.133, 0.319, 0.609,
1.189, 1.788, 1.616, 1.463, 1.368, 1.396), Flask3 = c(0.045,
0.129, 0.327, 0.603, 1.134, 1.658, 1.555, 1.385, 1.34, 1.4
), Flask4 = c(0.046, 0.117, 0.308, 0.554, 0.964, 1.478, 1.544,
1.34, 1.334, 1.34)), row.names = c(NA, -10L), spec = structure(list(
cols = list(DSI = structure(list(), class = c("collector_double",
"collector")), `Flask 1` = structure(list(), class = c("collector_double",
"collector")), `Flask 2` = structure(list(), class = c("collector_double",
"collector")), `Flask 3` = structure(list(), class = c("collector_double",
"collector")), `Flask 4` = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), delim = ","), class = "col_spec"), problems = <pointer: 0x000001f6ae38ab20>, class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"))
The loop:
slopes <- rep(NA, nrow(DIP)-2)
for( i in 1:length(slopes)){
slopes[i] <- lm(Flask1 ~ DSI, data=DIP[i:(i 2), ])$coefficients[2]
}
print(slopes)
Which returns
[1] 0.06700 0.12500 0.21600 0.30950 0.12800 -0.07950 -0.06325 -0.01750
I am trying to make this loop a function so I can use it for the other columns in my data as well as other data. I tried this function:
get_slopes <- function (Data, X, Y) {
slopes <- rep(NA, nrow(Data)-2)
for( i in 1:length(slopes)){
slopes[i] <- lm(Y ~ X, data=Data[i:(i 2), ])$coefficients[2]
}
print(slopes)
}
But when I run
get_slopes(Data = DIP, X = DIP$DSI, Y = DIP$Flask1)
It returns
[1] 0.09684848 0.09684848 0.09684848 0.09684848 0.09684848 0.09684848 0.09684848 0.09684848
Where am I going wrong? How do I change my function to return the same values as the loop pre-function?
CodePudding user response:
Try this,
get_slopes <- function (Data, X, Y) {
slopes <- rep(NA, nrow(Data)-2)
for( i in 1:length(slopes)){
slopes[i] <- lm(paste(Y ,"~", X), data=Data[i:(i 2), ])$coefficients[2]
}
print(slopes)
}
and then,
get_slopes(Data = DIP, X = "DSI", Y = "Flask1")
Alternatively, you could use the purrr::map_dbl()
function, e.g.
get_slopes <- function(Data, X, Y) {
purrr::map_dbl(1:length(Data), ~ lm(paste(Y, "~", X), data=Data[.x:(.x 2), ])$coefficients[2])
}
get_slopes(Data = DIP, X = "DSI", Y = "Flask1")
[1] 0.0670 0.1250 0.2160 0.3095 0.1280