Home > Enterprise >  Function using for loop returns different values
Function using for loop returns different values

Time:05-19

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
  • Related