From 3ae8b44a5651b98d2e8d95d42064362c86673b98 Mon Sep 17 00:00:00 2001 From: june861 Date: Wed, 23 Oct 2024 09:29:36 +0800 Subject: [PATCH 1/4] add: my code --- mycode/test.r | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 mycode/test.r diff --git a/mycode/test.r b/mycode/test.r new file mode 100644 index 0000000..e69de29 From 3f8374c3b2c23fa905561713d877d5f696fe53a8 Mon Sep 17 00:00:00 2001 From: june861 Date: Wed, 23 Oct 2024 16:27:53 +0800 Subject: [PATCH 2/4] add:my pkg --- mycode/test.r | 24 +++++++++++++++++++ mypkgs/mylin2024111211/.Rbuildignore | 2 ++ mypkgs/mylin2024111211/.gitignore | 1 + mypkgs/mylin2024111211/DESCRIPTION | 12 ++++++++++ mypkgs/mylin2024111211/NAMESPACE | 6 +++++ mypkgs/mylin2024111211/R/lin_reg.R | 24 +++++++++++++++++++ mypkgs/mylin2024111211/R/predict.R | 11 +++++++++ mypkgs/mylin2024111211/R/print.R | 10 ++++++++ mypkgs/mylin2024111211/man/lin_reg.Rd | 19 +++++++++++++++ mypkgs/mylin2024111211/man/predict.Rd | 19 +++++++++++++++ mypkgs/mylin2024111211/man/print.lm.Rd | 17 +++++++++++++ mypkgs/mylin2024111211/man/save_model.Rd | 19 +++++++++++++++ mypkgs/mylin2024111211/my_model_file.rda | Bin 0 -> 185 bytes mypkgs/mylin2024111211/mylin2024111211.Rproj | 17 +++++++++++++ 14 files changed, 181 insertions(+) create mode 100644 mypkgs/mylin2024111211/.Rbuildignore create mode 100644 mypkgs/mylin2024111211/.gitignore create mode 100644 mypkgs/mylin2024111211/DESCRIPTION create mode 100644 mypkgs/mylin2024111211/NAMESPACE create mode 100644 mypkgs/mylin2024111211/R/lin_reg.R create mode 100644 mypkgs/mylin2024111211/R/predict.R create mode 100644 mypkgs/mylin2024111211/R/print.R create mode 100644 mypkgs/mylin2024111211/man/lin_reg.Rd create mode 100644 mypkgs/mylin2024111211/man/predict.Rd create mode 100644 mypkgs/mylin2024111211/man/print.lm.Rd create mode 100644 mypkgs/mylin2024111211/man/save_model.Rd create mode 100644 mypkgs/mylin2024111211/my_model_file.rda create mode 100644 mypkgs/mylin2024111211/mylin2024111211.Rproj diff --git a/mycode/test.r b/mycode/test.r index e69de29..a25c037 100644 --- a/mycode/test.r +++ b/mycode/test.r @@ -0,0 +1,24 @@ +library(mylin2024111211) +# build a linear random datas +x <- rnorm(100) +y <- 20 * x + 23 + rnorm(100) +data <- data.frame(x, y) +# draw plot +library(ggplot2) +# 绘制散点图 +ggplot(data1, aes(x = x, y = y)) + + geom_point(color = "blue", size = 2) + # 绘制散点 + labs(title = "Scatter Plot", x = "X Values", y = "Y Values") + # 添加标题和标签 + theme_minimal() +# fit model +model <- lin_reg(y ~ x, data = data) +abline(model, col = "red") +print(model) +model_save_dir <- getwd() +model_save_name <- "my_linear_mode.rda" +filename <- paste(model_save_dir, model_save_name, sep = '/') +save_model(model = model, filename = filename) +load(filename) +data2 <- data.frame(x = 1:10) +predictions <- predict(model, data2) +print(predictions) diff --git a/mypkgs/mylin2024111211/.Rbuildignore b/mypkgs/mylin2024111211/.Rbuildignore new file mode 100644 index 0000000..813f03a --- /dev/null +++ b/mypkgs/mylin2024111211/.Rbuildignore @@ -0,0 +1,2 @@ +^mylin2024111211\.Rproj$ +^\.Rproj\.user$ diff --git a/mypkgs/mylin2024111211/.gitignore b/mypkgs/mylin2024111211/.gitignore new file mode 100644 index 0000000..cd67eac --- /dev/null +++ b/mypkgs/mylin2024111211/.gitignore @@ -0,0 +1 @@ +.Rproj.user diff --git a/mypkgs/mylin2024111211/DESCRIPTION b/mypkgs/mylin2024111211/DESCRIPTION new file mode 100644 index 0000000..825fe46 --- /dev/null +++ b/mypkgs/mylin2024111211/DESCRIPTION @@ -0,0 +1,12 @@ +Package: mylin2024111211 +Title: What the Package Does (One Line, Title Case) +Version: 0.0.0.9000 +Authors@R: + person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), + comment = c(ORCID = "YOUR-ORCID-ID")) +Description: What the package does (one paragraph). +License: `use_mit_license()`, `use_gpl3_license()` or friends to pick a + license +Encoding: UTF-8 +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.3.2 diff --git a/mypkgs/mylin2024111211/NAMESPACE b/mypkgs/mylin2024111211/NAMESPACE new file mode 100644 index 0000000..daad58b --- /dev/null +++ b/mypkgs/mylin2024111211/NAMESPACE @@ -0,0 +1,6 @@ +# Generated by roxygen2: do not edit by hand + +S3method(print,lm) +export(lin_reg) +export(predict) +export(save_model) diff --git a/mypkgs/mylin2024111211/R/lin_reg.R b/mypkgs/mylin2024111211/R/lin_reg.R new file mode 100644 index 0000000..9c6091f --- /dev/null +++ b/mypkgs/mylin2024111211/R/lin_reg.R @@ -0,0 +1,24 @@ +#' Linear Regression Model +#' +#' @description train a linear model +#' @param formula describle model formula +#' @param data data build from data.frame +#' @return return a list consist of coefficiences and formula +#' @export +lin_reg <- function(formula, data) { + x <- model.matrix(formula, data)[, -1] + y <- data[[as.character(formula[[2]])]] + coef <- solve(t(x) %*% x) %*% t(x) %*% y + list(coefficients = coef, formula = formula) +} + +#' Linear Regression Model +#' +#' @description save model +#' @param mode the linear model you want to save +#' @param filename the save model file name +#' @return none +#' @export +save_model <- function(model, filename) { + save(model, file = filename) +} diff --git a/mypkgs/mylin2024111211/R/predict.R b/mypkgs/mylin2024111211/R/predict.R new file mode 100644 index 0000000..377ad23 --- /dev/null +++ b/mypkgs/mylin2024111211/R/predict.R @@ -0,0 +1,11 @@ +#' Predict via Linear Regression Model +#' +#' @description train a linear model +#' @param model describle model formula +#' @param newdata build from data.frame +#' @return return a list consist of coefficiences and formula +#' @export +predict <- function(model, newdata) { + x_new <- cbind(1, newdata) + return(x_new %*% model$coefficients) +} \ No newline at end of file diff --git a/mypkgs/mylin2024111211/R/print.R b/mypkgs/mylin2024111211/R/print.R new file mode 100644 index 0000000..4689cce --- /dev/null +++ b/mypkgs/mylin2024111211/R/print.R @@ -0,0 +1,10 @@ +#' Linear Regression Model +#' +#' @description train a linear model +#' @param model the model you want to display +#' @return return a list consist of coefficiences and formula +#' @export +print.lm <- function(model) { + cat("Coefficients:\n") + print(model$coefficients) +} \ No newline at end of file diff --git a/mypkgs/mylin2024111211/man/lin_reg.Rd b/mypkgs/mylin2024111211/man/lin_reg.Rd new file mode 100644 index 0000000..c28f36c --- /dev/null +++ b/mypkgs/mylin2024111211/man/lin_reg.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/lin_reg.R +\name{lin_reg} +\alias{lin_reg} +\title{Linear Regression Model} +\usage{ +lin_reg(formula, data) +} +\arguments{ +\item{formula}{describle model formula} + +\item{data}{data build from data.frame} +} +\value{ +return a list consist of coefficiences and formula +} +\description{ +train a linear model +} diff --git a/mypkgs/mylin2024111211/man/predict.Rd b/mypkgs/mylin2024111211/man/predict.Rd new file mode 100644 index 0000000..718ad82 --- /dev/null +++ b/mypkgs/mylin2024111211/man/predict.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/predict.R +\name{predict} +\alias{predict} +\title{Predict via Linear Regression Model} +\usage{ +predict(model, newdata) +} +\arguments{ +\item{model}{describle model formula} + +\item{newdata}{build from data.frame} +} +\value{ +return a list consist of coefficiences and formula +} +\description{ +train a linear model +} diff --git a/mypkgs/mylin2024111211/man/print.lm.Rd b/mypkgs/mylin2024111211/man/print.lm.Rd new file mode 100644 index 0000000..94e85f3 --- /dev/null +++ b/mypkgs/mylin2024111211/man/print.lm.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/print.R +\name{print.lm} +\alias{print.lm} +\title{Linear Regression Model} +\usage{ +\method{print}{lm}(model) +} +\arguments{ +\item{model}{the model you want to display} +} +\value{ +return a list consist of coefficiences and formula +} +\description{ +train a linear model +} diff --git a/mypkgs/mylin2024111211/man/save_model.Rd b/mypkgs/mylin2024111211/man/save_model.Rd new file mode 100644 index 0000000..61fb8bc --- /dev/null +++ b/mypkgs/mylin2024111211/man/save_model.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/lin_reg.R +\name{save_model} +\alias{save_model} +\title{Linear Regression Model} +\usage{ +save_model(model, filename) +} +\arguments{ +\item{filename}{the save model file name} + +\item{mode}{the linear model you want to save} +} +\value{ +none +} +\description{ +save model +} diff --git a/mypkgs/mylin2024111211/my_model_file.rda b/mypkgs/mylin2024111211/my_model_file.rda new file mode 100644 index 0000000000000000000000000000000000000000..15be7eeaec5ca71445b67fc294eac8534eee2516 GIT binary patch literal 185 zcmV;q07m~GiwFP!000001`BeDFy@NjVqjokW?*4qWMF0mG8tH%11ycr7#LWXfE-2! z76wj`U~Ya&Y7PSflQ572lwjfmNjjLMglylnMGH+ab4q3|km7|X1qws(KcEa7y1B_Y ziN(c0h5(Wvds==`ZfQ;;npz$`*SxaKqWrwv)VvZP|1ZQ$xIAMW+(M{8CAvTbL<_1D n@)C1XVNPIz*_E81nwFNCoC&n57{gg$YySZNpR|p&KLG#$8;D4> literal 0 HcmV?d00001 diff --git a/mypkgs/mylin2024111211/mylin2024111211.Rproj b/mypkgs/mylin2024111211/mylin2024111211.Rproj new file mode 100644 index 0000000..aaa62a5 --- /dev/null +++ b/mypkgs/mylin2024111211/mylin2024111211.Rproj @@ -0,0 +1,17 @@ +Version: 1.0 + +RestoreWorkspace: No +SaveWorkspace: No +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +Encoding: UTF-8 + +AutoAppendNewline: Yes +StripTrailingWhitespace: Yes +LineEndingConversion: Posix + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace From d81c1f11f91ac9edb12edc32d1bc086c3b572917 Mon Sep 17 00:00:00 2001 From: june861 Date: Wed, 23 Oct 2024 17:42:11 +0800 Subject: [PATCH 3/4] add: --- learn_lm.R | 78 +++++++++++++++++++++++ mycode/test.r | 67 +++++++++++++------ mycode/test1.R | 30 +++++++++ mypkgs/mylin2024111211/R/lin_reg.R | 16 +++-- mypkgs/mylin2024111211/R/predict.R | 4 +- mypkgs/mylin2024111211/my_model_file.rda | Bin 185 -> 0 bytes 6 files changed, 170 insertions(+), 25 deletions(-) create mode 100644 learn_lm.R create mode 100644 mycode/test1.R delete mode 100644 mypkgs/mylin2024111211/my_model_file.rda diff --git a/learn_lm.R b/learn_lm.R new file mode 100644 index 0000000..aee9891 --- /dev/null +++ b/learn_lm.R @@ -0,0 +1,78 @@ +learn_ml <- function (formula, data, subset, weights, na.action, method = "qr", + model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, + contrasts = NULL, offset, ...) +{ + ret.x <- x + ret.y <- y + cl <- match.call() + mf <- match.call(expand.dots = FALSE) + m <- match(c("formula", "data", "subset", "weights", "na.action", + "offset"), names(mf), 0L) + mf <- mf[c(1L, m)] + mf$drop.unused.levels <- TRUE + mf[[1L]] <- quote(stats::model.frame) + mf <- eval(mf, parent.frame()) + if (method == "model.frame") + return(mf) + else if (method != "qr") + warning(gettextf("method = '%s' is not supported. Using 'qr'", + method), domain = NA) + mt <- attr(mf, "terms") + y <- model.response(mf, "numeric") + w <- as.vector(model.weights(mf)) + if (!is.null(w) && !is.numeric(w)) + stop("'weights' must be a numeric vector") + offset <- model.offset(mf) + mlm <- is.matrix(y) + ny <- if (mlm) + nrow(y) + else length(y) + if (!is.null(offset)) { + if (!mlm) + offset <- as.vector(offset) + if (NROW(offset) != ny) + stop(gettextf("number of offsets is %d, should equal %d (number of observations)", + NROW(offset), ny), domain = NA) + } + if (is.empty.model(mt)) { + x <- NULL + z <- list(coefficients = if (mlm) matrix(NA_real_, 0, + ncol(y)) else numeric(), residuals = y, fitted.values = 0 * + y, weights = w, rank = 0L, df.residual = if (!is.null(w)) sum(w != + 0) else ny) + if (!is.null(offset)) { + z$fitted.values <- offset + z$residuals <- y - offset + } + } + else { + x <- model.matrix(mt, mf, contrasts) + z <- if (is.null(w)) + lm.fit(x, y, offset = offset, singular.ok = singular.ok, + ...) + else lm.wfit(x, y, w, offset = offset, singular.ok = singular.ok, + ...) + } + class(z) <- c(if (mlm) "mlm", "lm") + z$na.action <- attr(mf, "na.action") + z$offset <- offset + z$contrasts <- attr(x, "contrasts") + z$xlevels <- .getXlevels(mt, mf) + z$call <- cl + z$terms <- mt + if (model) + z$model <- mf + if (ret.x) + z$x <- x + if (ret.y) + z$y <- y + if (!qr) + z$qr <- NULL + z +} + +set.seed(123) # 保证随机数可重复 +x <- rnorm(100) +y <- 20 * x + 23 + rnorm(100) + +model <- learn_ml(y ~ x, data = data.frame(x = x, y = y)) \ No newline at end of file diff --git a/mycode/test.r b/mycode/test.r index a25c037..ff00b13 100644 --- a/mycode/test.r +++ b/mycode/test.r @@ -1,24 +1,51 @@ +# library(mylin2024111211) +# # build a linear random datas +# x <- rnorm(100) +# y <- 20 * x + 23 + rnorm(100) +# data <- data.frame(x, y) +# # draw plot +# library(ggplot2) +# # 绘制散点图 +# ggplot(data1, aes(x = x, y = y)) + +# geom_point(color = "blue", size = 2) + # 绘制散点 +# labs(title = "Scatter Plot", x = "X Values", y = "Y Values") + # 添加标题和标签 +# theme_minimal() +# # fit model +# model <- lin_reg(y ~ x, data = data) +# abline(model, col = "red") +# print(model) +# model_save_dir <- getwd() +# model_save_name <- "my_linear_mode.rda" +# filename <- paste(model_save_dir, model_save_name, sep = '/') +# save_model(model = model, filename = filename) +# load(filename) +# data2 <- data.frame(x = 1:10) +# predictions <- predict(model, data2) +# print(predictions) + + + library(mylin2024111211) -# build a linear random datas + +# 创建一些数据 +set.seed(123) # 保证随机数可重复 x <- rnorm(100) y <- 20 * x + 23 + rnorm(100) -data <- data.frame(x, y) -# draw plot -library(ggplot2) -# 绘制散点图 -ggplot(data1, aes(x = x, y = y)) + - geom_point(color = "blue", size = 2) + # 绘制散点 - labs(title = "Scatter Plot", x = "X Values", y = "Y Values") + # 添加标题和标签 - theme_minimal() -# fit model -model <- lin_reg(y ~ x, data = data) -abline(model, col = "red") + +# 使用 lin_reg 训练模型 +model <- lin_reg(y ~ x, data = data.frame(x = x, y = y)) + +# 输出模型信息 print(model) -model_save_dir <- getwd() -model_save_name <- "my_linear_mode.rda" -filename <- paste(model_save_dir, model_save_name, sep = '/') -save_model(model = model, filename = filename) -load(filename) -data2 <- data.frame(x = 1:10) -predictions <- predict(model, data2) -print(predictions) + +# # 预测值 +predictions <- predict(model, data.frame(x = seq(min(x), + max(x), length.out = 10))) + +# 绘制原始数据与预测线 +plot(x, y, pch = 19, col = "blue", main = "Linear Regression Model", + xlab = "x", ylab = "y") +abline(model, col = 'orange') +lines(seq(min(x), max(x), length.out = 10), predictions, col = "red", lwd = 2) +legend("topleft", legend = c("Actual Data", "Fitted Line"), + col = c("blue", "red"), pch = c(19, NA), lty = c(NA, 1), lwd = 2) \ No newline at end of file diff --git a/mycode/test1.R b/mycode/test1.R new file mode 100644 index 0000000..4a866d5 --- /dev/null +++ b/mycode/test1.R @@ -0,0 +1,30 @@ +if (!requireNamespace("animation")) install.packages("animation") +library(animation) + +# 设置动画参数 +interval <- 20 +ani.options(interval = interval) # 设置帧间隔时间 + +# 动态拟合线性模型 +dynamic_fit <- function(n_points_max = 100, step = 20) { + set.seed(123) # 设置随机种子确保可重复性 + x <- rnorm(n_points_max) + y <- 20 * x + 23 + rnorm(n_points_max) # 生成带有噪声的线性数据 + + saveGIF({ + for (n in seq(step, n_points_max, by = step)) { + # 使用前n个点拟合模型 + model <- lm(y ~ x, data = data.frame(x = x[1:n], y = y[1:n])) + # 预测整个x范围内的y值 + predictions <- predict(model, data.frame(x = seq(min(x), max(x), length.out = 100))) + # 绘制当前拟合线 + plot(x[1:n], y[1:n], pch=19, col="blue", main=paste0("Fitting with ", n, " points"), + xlab = "x", ylab = "y") + lines(seq(min(x), max(x), length.out = 100), predictions, col="red", lwd=2) + + Sys.sleep(interval) # 暂停一下,让动画效果更明显 + } + }, movie.name = "dynamic_fit.gif", interval = 0.1) +} + +dynamic_fit() \ No newline at end of file diff --git a/mypkgs/mylin2024111211/R/lin_reg.R b/mypkgs/mylin2024111211/R/lin_reg.R index 9c6091f..7ff4514 100644 --- a/mypkgs/mylin2024111211/R/lin_reg.R +++ b/mypkgs/mylin2024111211/R/lin_reg.R @@ -6,10 +6,18 @@ #' @return return a list consist of coefficiences and formula #' @export lin_reg <- function(formula, data) { - x <- model.matrix(formula, data)[, -1] - y <- data[[as.character(formula[[2]])]] - coef <- solve(t(x) %*% x) %*% t(x) %*% y - list(coefficients = coef, formula = formula) + m <- model.matrix(formula, data) + y <- model.response(model.frame(formula, data)) + # Solve for coefficients using least squares + coef <- solve(crossprod(m), crossprod(m, y)) + # Create a list that holds the model information + model <- list(coefficients = coef, + residuals = y - m %*% coef, + call = match.call(), + terms = terms(formula), + rank = length(coef)) + class(model) <- "mylin" + return(model) } #' Linear Regression Model diff --git a/mypkgs/mylin2024111211/R/predict.R b/mypkgs/mylin2024111211/R/predict.R index 377ad23..7da5cdf 100644 --- a/mypkgs/mylin2024111211/R/predict.R +++ b/mypkgs/mylin2024111211/R/predict.R @@ -7,5 +7,7 @@ #' @export predict <- function(model, newdata) { x_new <- cbind(1, newdata) - return(x_new %*% model$coefficients) + # conver x_new to numerical + x_new_mat <- as.matrix(x_new) + return(x_new_mat %*% model$coefficients) } \ No newline at end of file diff --git a/mypkgs/mylin2024111211/my_model_file.rda b/mypkgs/mylin2024111211/my_model_file.rda deleted file mode 100644 index 15be7eeaec5ca71445b67fc294eac8534eee2516..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185 zcmV;q07m~GiwFP!000001`BeDFy@NjVqjokW?*4qWMF0mG8tH%11ycr7#LWXfE-2! z76wj`U~Ya&Y7PSflQ572lwjfmNjjLMglylnMGH+ab4q3|km7|X1qws(KcEa7y1B_Y ziN(c0h5(Wvds==`ZfQ;;npz$`*SxaKqWrwv)VvZP|1ZQ$xIAMW+(M{8CAvTbL<_1D n@)C1XVNPIz*_E81nwFNCoC&n57{gg$YySZNpR|p&KLG#$8;D4> From 61150f5accf1c548d85032ca84ce064e52da362e Mon Sep 17 00:00:00 2001 From: june861 Date: Sat, 26 Oct 2024 12:51:04 +0800 Subject: [PATCH 4/4] add: modify --- learn_lm.R | 3 +- mycode/T.R | 70 ++++++++++++++++++++ mycode/test.r | 51 -------------- mypkgs/mylin2024111211/R/lin_reg.R | 95 ++++++++++++++++++++------- mypkgs/mylin2024111211/R/predict.R | 26 +++++--- mypkgs/mylin2024111211/R/print.R | 16 +++-- mypkgs/mylin2024111211/man/lin_reg.Rd | 42 +++++++++++- 7 files changed, 206 insertions(+), 97 deletions(-) create mode 100644 mycode/T.R delete mode 100644 mycode/test.r diff --git a/learn_lm.R b/learn_lm.R index aee9891..852456b 100644 --- a/learn_lm.R +++ b/learn_lm.R @@ -1,7 +1,6 @@ learn_ml <- function (formula, data, subset, weights, na.action, method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, - contrasts = NULL, offset, ...) -{ + contrasts = NULL, offset, ...) { ret.x <- x ret.y <- y cl <- match.call() diff --git a/mycode/T.R b/mycode/T.R new file mode 100644 index 0000000..972912c --- /dev/null +++ b/mycode/T.R @@ -0,0 +1,70 @@ +lin_reg <- function(formula, data, subset, save_model = TRUE, + weights = NULL, na.action = na.fail, + model_save_path = NULL, ...) { + + mf <- match.call(expand.dots = FALSE) + mf <- mf[c(1L, match(c("formula", "data", "subset", "save_model", "weights", "na.action", "model_save_path"), names(mf), 0L))] + mf$drop.unused.levels <- TRUE + mf[[1L]] <- as.name("model.frame") + mf <- eval(mf, parent.frame()) + + mt <- attr(mf, "terms") + y <- model.response(mf, "numeric") + + if (!is.null(weights)) { + if (!is.numeric(weights)) + stop("'weights' must be a numeric vector") + } + + x <- model.matrix(mt, mf) + + if (is.null(weights)) { + coef <- lm.fit(x, y)$coefficients + } else { + coef <- lm.wfit(x, y, weights)$coefficients + } + + model <- structure(list(coefficients = coef, residuals = y - x %*% coef, + call = match.call(), terms = mt, model = mf, + na.action = attr(mf, "na.action"), + xlevels = .getXlevels(mt, mf)), + class = "lin_reg") + + if (save_model) { + if (is.null(model_save_path)) { + curr_dir <- getwd() + model_save_path <- paste(curr_dir, "linear_model.rda", sep = "/") + } + + # check model_save_path fairness + dir_path <- dirname(model_save_path) + if (!file.exists(dir_path)) { + dir.create(dir_path, recursive = TRUE) + } + + # Check if file already exists, modify filename if needed + base_name <- basename(model_save_path) + pattern <- paste0("^", gsub("[.]", "\\.", base_name), "$") + dir_files <- list.files(dir_path, pattern = pattern, full.names = FALSE) + + i <- 1 + basename_omit <- strsplit(base_name, "\\.")[[1L]][[1L]] + while (base_name %in% dir_files) { + base_name <- paste0(basename_omit, i, ".rda") + i <- i + 1 + } + + model_save_path <- file.path(dir_path, base_name) + print(cat("model will be save in ", model_save_path)) + save(model, file = model_save_path) + } + + model +} + +# 创建一些数据 +x <- rnorm(100) +y <- 20 * x + 23 + rnorm(100) + +# 使用 lin_reg 训练模型 +model <- lin_reg(y ~ x, data = data.frame(x = x, y = y)) \ No newline at end of file diff --git a/mycode/test.r b/mycode/test.r deleted file mode 100644 index ff00b13..0000000 --- a/mycode/test.r +++ /dev/null @@ -1,51 +0,0 @@ -# library(mylin2024111211) -# # build a linear random datas -# x <- rnorm(100) -# y <- 20 * x + 23 + rnorm(100) -# data <- data.frame(x, y) -# # draw plot -# library(ggplot2) -# # 绘制散点图 -# ggplot(data1, aes(x = x, y = y)) + -# geom_point(color = "blue", size = 2) + # 绘制散点 -# labs(title = "Scatter Plot", x = "X Values", y = "Y Values") + # 添加标题和标签 -# theme_minimal() -# # fit model -# model <- lin_reg(y ~ x, data = data) -# abline(model, col = "red") -# print(model) -# model_save_dir <- getwd() -# model_save_name <- "my_linear_mode.rda" -# filename <- paste(model_save_dir, model_save_name, sep = '/') -# save_model(model = model, filename = filename) -# load(filename) -# data2 <- data.frame(x = 1:10) -# predictions <- predict(model, data2) -# print(predictions) - - - -library(mylin2024111211) - -# 创建一些数据 -set.seed(123) # 保证随机数可重复 -x <- rnorm(100) -y <- 20 * x + 23 + rnorm(100) - -# 使用 lin_reg 训练模型 -model <- lin_reg(y ~ x, data = data.frame(x = x, y = y)) - -# 输出模型信息 -print(model) - -# # 预测值 -predictions <- predict(model, data.frame(x = seq(min(x), - max(x), length.out = 10))) - -# 绘制原始数据与预测线 -plot(x, y, pch = 19, col = "blue", main = "Linear Regression Model", - xlab = "x", ylab = "y") -abline(model, col = 'orange') -lines(seq(min(x), max(x), length.out = 10), predictions, col = "red", lwd = 2) -legend("topleft", legend = c("Actual Data", "Fitted Line"), - col = c("blue", "red"), pch = c(19, NA), lty = c(NA, 1), lwd = 2) \ No newline at end of file diff --git a/mypkgs/mylin2024111211/R/lin_reg.R b/mypkgs/mylin2024111211/R/lin_reg.R index 7ff4514..79f417c 100644 --- a/mypkgs/mylin2024111211/R/lin_reg.R +++ b/mypkgs/mylin2024111211/R/lin_reg.R @@ -1,32 +1,77 @@ #' Linear Regression Model #' #' @description train a linear model -#' @param formula describle model formula -#' @param data data build from data.frame +#' @param formula describle model formula, such as y ~ x +#' @param data data build from data.frame, such as data.frame(x = x, y = y) +#' @param subset Specify a subset, such as fitting only the portion of +#' data greater than 0 in the dataset. +#' @param save_model whether save model. Default TRUE +#' @param weights Optional vector of case weights. +#' @param na.action Function indicating what should happen when the data contain NAs. +#' default na.fail, optional is [na.omit, ] +#' @param model_save_path User define the model save path. #' @return return a list consist of coefficiences and formula #' @export -lin_reg <- function(formula, data) { - m <- model.matrix(formula, data) - y <- model.response(model.frame(formula, data)) - # Solve for coefficients using least squares - coef <- solve(crossprod(m), crossprod(m, y)) - # Create a list that holds the model information - model <- list(coefficients = coef, - residuals = y - m %*% coef, - call = match.call(), - terms = terms(formula), - rank = length(coef)) - class(model) <- "mylin" - return(model) -} +lin_reg <- function(formula, data, subset, save_model = TRUE, + weights = NULL, na.action = na.fail, + model_save_path = NULL, ...) { -#' Linear Regression Model -#' -#' @description save model -#' @param mode the linear model you want to save -#' @param filename the save model file name -#' @return none -#' @export -save_model <- function(model, filename) { - save(model, file = filename) + mf <- match.call(expand.dots = FALSE) + mf <- mf[c(1L, match(c("formula", "data", "subset", "save_model", "weights", "na.action", "model_save_path"), names(mf), 0L))] + mf$drop.unused.levels <- TRUE + mf[[1L]] <- as.name("model.frame") + mf <- eval(mf, parent.frame()) + + mt <- attr(mf, "terms") + y <- model.response(mf, "numeric") + + if (!is.null(weights)) { + if (!is.numeric(weights)) + stop("'weights' must be a numeric vector") + } + + x <- model.matrix(mt, mf) + + if (is.null(weights)) { + coef <- lm.fit(x, y)$coefficients + } else { + coef <- lm.wfit(x, y, weights)$coefficients + } + + model <- structure(list(coefficients = coef, residuals = y - x %*% coef, + call = match.call(), terms = mt, model = mf, + na.action = attr(mf, "na.action"), + xlevels = .getXlevels(mt, mf)), + class = "lin_reg") + + if (save_model) { + if (is.null(model_save_path)) { + curr_dir <- getwd() + model_save_path <- paste(curr_dir, "linear_model.rda", sep = "/") + } + + # check model_save_path fairness + dir_path <- dirname(model_save_path) + if (!file.exists(dir_path)) { + dir.create(dir_path, recursive = TRUE) + } + + # Check if file already exists, modify filename if needed + base_name <- basename(model_save_path) + pattern <- paste0("^", gsub("[.]", "\\.", base_name), "$") + dir_files <- list.files(dir_path, pattern = pattern, full.names = FALSE) + + i <- 1 + basename_omit <- strsplit(base_name, "\\.")[[1L]][[1L]] + while (base_name %in% dir_files) { + base_name <- paste0(basename_omit, i, ".rda") + i <- i + 1 + } + + model_save_path <- file.path(dir_path, base_name) + print(cat("model will be save in ", model_save_path)) + save(model, file = model_save_path) + } + + model } diff --git a/mypkgs/mylin2024111211/R/predict.R b/mypkgs/mylin2024111211/R/predict.R index 7da5cdf..33af18e 100644 --- a/mypkgs/mylin2024111211/R/predict.R +++ b/mypkgs/mylin2024111211/R/predict.R @@ -1,13 +1,19 @@ -#' Predict via Linear Regression Model +#' Predict from a Simple Linear Regression Model #' -#' @description train a linear model -#' @param model describle model formula -#' @param newdata build from data.frame -#' @return return a list consist of coefficiences and formula +#' Predict new responses given the regression model and new input values. +#' +#' @param object An object of class "mylin". +#' @param newdata A data frame or matrix of new input values. +#' @param ... Additional arguments. +#' @return A vector of predicted values. #' @export -predict <- function(model, newdata) { - x_new <- cbind(1, newdata) - # conver x_new to numerical - x_new_mat <- as.matrix(x_new) - return(x_new_mat %*% model$coefficients) +predict.mylin <- function(object, newdata, ...) { + # Extract the coefficients + coef <- object$coefficients + # Create the model matrix for the new data + mm <- model.frame(object$terms, newdata) + x <- model.matrix(object$terms, mm) + # Compute predictions + predict <- x %*% coef + predict } \ No newline at end of file diff --git a/mypkgs/mylin2024111211/R/print.R b/mypkgs/mylin2024111211/R/print.R index 4689cce..e7c3f68 100644 --- a/mypkgs/mylin2024111211/R/print.R +++ b/mypkgs/mylin2024111211/R/print.R @@ -1,10 +1,14 @@ -#' Linear Regression Model +#' Print a Simple Linear Regression Model Summary #' -#' @description train a linear model -#' @param model the model you want to display -#' @return return a list consist of coefficiences and formula +#' Prints a summary of a simple linear regression model. +#' +#' @param x An object of class "mylin". +#' @param ... Additional arguments. #' @export -print.lm <- function(model) { +print.mylin <- function(x, ...) { + cat("\nCall:\n", deparse(x$call), "\n\n") cat("Coefficients:\n") - print(model$coefficients) + print.default(format(x$coefficients), print.gap = 2L, quote = FALSE) + cat("\n") + invisible(x) } \ No newline at end of file diff --git a/mypkgs/mylin2024111211/man/lin_reg.Rd b/mypkgs/mylin2024111211/man/lin_reg.Rd index c28f36c..06afc0d 100644 --- a/mypkgs/mylin2024111211/man/lin_reg.Rd +++ b/mypkgs/mylin2024111211/man/lin_reg.Rd @@ -4,12 +4,48 @@ \alias{lin_reg} \title{Linear Regression Model} \usage{ -lin_reg(formula, data) +lin_reg( + formula, + data, + subset, + weights, + na.action, + method = "qr", + model = TRUE, + return_x = FALSE, + return_y = FALSE, + qr = TRUE, + singular.ok = TRUE, + contrasts = NULL, + offset +) } \arguments{ -\item{formula}{describle model formula} +\item{formula}{describle model formula, such as y ~ x} -\item{data}{data build from data.frame} +\item{data}{data build from data.frame, such as data.frame(x = x, y = y)} + +\item{subset}{none} + +\item{weights}{none} + +\item{na.action}{none} + +\item{method}{which method is used to fit linear model.} + +\item{model}{whether return a model class.} + +\item{return_x}{whether need to return designer matrix. default False} + +\item{return_y}{whether need to return response variable . default False} + +\item{qr}{none} + +\item{singular.ok}{none} + +\item{contrasts}{none} + +\item{offset}{none} } \value{ return a list consist of coefficiences and formula