tjr tjr - 1 month ago 11
R Question

Find point on curve with slope equal to 1

I have the following dataframe, "hr". I want to find the point on the curve where the slope of this plot:

plot(hr$ff,hr$hr1to100)


equals 1. The slope could come from any model, for example:

lo <- loess(hr$hr1to100~hr$ff)
out = predict(lo,xl)


or

model<- lm(hr$hr1to100~hr$ff)



dput(hr)
structure(list(hr1to100 = c(0.000902527075812275, 0.00180505415162455,
0.0036101083032491, 0.00451263537906137, 0.00631768953068592,
0.0072202166064982, 0.00902527075812275, 0.00992779783393502,
0.0117328519855596, 0.0135379061371841, 0.0153429602888087, 0.0171480144404332,
0.0180505415162455, 0.01985559566787, 0.0216606498194946, 0.0234657039711191,
0.0252707581227437, 0.0270758122743682, 0.0288808664259928, 0.0306859205776173,
0.0333935018050542, 0.0351985559566787, 0.0370036101083033, 0.0388086642599278,
0.0415162454873646, 0.0433212996389892, 0.046028880866426, 0.0478339350180505,
0.0505415162454874, 0.0523465703971119, 0.0550541516245487, 0.0577617328519856,
0.0604693140794224, 0.0631768953068592, 0.065884476534296, 0.0685920577617329,
0.0712996389891697, 0.0740072202166065, 0.0767148014440433, 0.0794223826714801,
0.0830324909747293, 0.0857400722021661, 0.0893501805054152, 0.0929602888086643,
0.0956678700361011, 0.0992779783393502, 0.102888086642599, 0.107400722021661,
0.11101083032491, 0.114620938628159, 0.11913357400722, 0.122743682310469,
0.127256317689531, 0.131768953068592, 0.136281588447653, 0.140794223826715,
0.145306859205776, 0.15072202166065, 0.156137184115523, 0.161552346570397,
0.166967509025271, 0.172382671480144, 0.17870036101083, 0.184115523465704,
0.19043321299639, 0.197653429602888, 0.203971119133574, 0.211191335740072,
0.219314079422383, 0.227436823104693, 0.235559566787004, 0.243682310469314,
0.252707581227437, 0.26173285198556, 0.270758122743682, 0.280685920577617,
0.290613718411552, 0.300541516245487, 0.311371841155235, 0.322202166064982,
0.333935018050542, 0.345667870036101, 0.358303249097473, 0.371841155234657,
0.385379061371841, 0.40072202166065, 0.416967509025271, 0.434115523465704,
0.453068592057762, 0.472924187725632, 0.494584837545126, 0.518050541516246,
0.545126353790614, 0.576714801444043, 0.612815884476534, 0.654332129963899,
0.707581227436823, 0.778880866425993, 0.894404332129964), ff = c(0.01,
0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12,
0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2, 0.21, 0.22, 0.23,
0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3, 0.31, 0.32, 0.33, 0.34,
0.35, 0.36, 0.37, 0.38, 0.39, 0.4, 0.41, 0.42, 0.43, 0.44, 0.45,
0.46, 0.47, 0.48, 0.49, 0.5, 0.51, 0.52, 0.53, 0.54, 0.55, 0.56,
0.57, 0.58, 0.59, 0.6, 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67,
0.68, 0.69, 0.7, 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78,
0.79, 0.8, 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89,
0.9, 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99)), .Names = c("hr1to100",
"ff"), row.names = c("1", "2", "3", "4", "5", "6", "7", "8",
"9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
"31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41",
"42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52",
"53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63",
"64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74",
"75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85",
"86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96",
"97", "98", "99"), class = "data.frame")


I have tried to fit answers from the following questions to my work, but without success but I think I'm missing something simple, maybe just a tangent?
Determining slopes with R code

http://stats.stackexchange.com/questions/76959/finding-inflection-points-in-r-from-smoothed-data

I think I want a vector of slopes along the line and then just select the x and y where slope equals 1 using:

which(slope==1)


But I don't know how to get the vector of slopes. Thanks.

Answer

We could use lag and which.min to determine the slope which is closest to 1 (in terms of absolute deviation). Basically, we calculate the slope at each point (x_i, y_i) by calculating

slope = (y_i - y_(i-1)) / (x_i - x_(i-1)).

hr$lag_hr1to100 <- lag(hr$hr1to100)
hr$lag_ff <- lag(hr$ff)
hr$slope <- (hr$hr1to100 - hr$lag_hr1to100) / (hr$ff - hr$lag_ff)

hr[which.min(abs(hr$slope - 1)),]

    hr1to100   ff lag_hr1to100 lag_ff     slope
76 0.2806859 0.76    0.2707581   0.75 0.9927798