我正在使用 ' segmented' 包来查找 R 中线性回归的断点
library(tidyverse)
library(segmented)
df <- data.frame(x = c(1:10), y = c(1,1,1,1,1,6:10))
lm_model <- lm(y ~ x, data = df)
seg_model <- segmented(obj = lm_model, seg.Z = ~ x)
Run Code Online (Sandbox Code Playgroud)
但是,如果我在 a 中运行相同的模型purrr:map,则分段会失败。
map_test <- df %>%
nest() %>%
mutate(map_lm = map(data, ~lm(y ~ x, data = .)),
param_map_lm = map(map_lm, tidy))
map_lm_model <- map_test[[2]][[1]]
map_seg_model <- segmented(obj = map_lm_model, seg.Z = ~ x)
Run Code Online (Sandbox Code Playgroud)
“is.data.frame(data) 中出现错误:对象‘.’ 未找到”
当从映射输出中提取的 lm 中获取 lm obj 时,segmented 无法找到底层数据。
然而,这两个线性模型对象看起来是相同的。
我实际上需要做的是一个更有用的映射,用于在数据帧的多个子集上运行 lm,然后在生成的 lm 上运行“分段”。
这与 glm() 和 purrr::map() 之间的交互基本上是相同的问题。
\n\nlm()捕获提供给它的表达式,它作为独立的情况运行良好。但是,当由 调用时map(),提供的表达式是.,它在该调用的直接上下文之外没有任何意义map(),并会导致您观察到的错误。
与另一个问题一样,一种解决方法是定义一个包装器lm(),直接在数据集上组成自定义调用,然后将其捕获lm()为未计算的表达式。
# Composes a custom lm() expression and evaluates it\nlm2 <- function(data, ...)\n eval( rlang::expr(lm(data=!!rlang::enexpr(data), !!!list(...))) )\n\n# Now mapping using lm2, instead of lm\nmap_test <- nest(df, data=everything()) %>% \n mutate(map_lm = map(data, lm2, y ~ x),\n param_map_lm = map(map_lm, broom::tidy))\n\n# The data is stored directly inside the lm object\n# segmented() now has no problems accessing it\nmap_lm_model <- map_test[[2]][[1]]\nmap_seg_model <- segmented(obj = map_lm_model, seg.Z = ~ x)\n# Call: segmented.lm(obj = map_lm_model, seg.Z = ~x)\n# \n# Meaningful coefficients of the linear terms:\n# (Intercept) x U1.x \n# 1.000e+00 6.344e-15 1.607e+00 \n# \n# Estimated Break-Point(s):\n# psi1.x \n# 3.889 \nRun Code Online (Sandbox Code Playgroud)\n\n或作为单mutate()链:
map_test <- nest(df, data=everything()) %>% \n mutate(map_lm = map(data, lm2, y ~ x),\n param_map_lm = map(map_lm, broom::tidy),\n seg_lm = map(map_lm, segmented, seg.Z=~x))\n# # A tibble: 1 x 4\n# data map_lm param_map_lm seg_lm \n# <list<df[,2]>> <list> <list> <list> \n# 1 [10 \xc3\x97 2] <lm> <tibble [2 \xc3\x97 5]> <segmentd>\nRun Code Online (Sandbox Code Playgroud)\n