R函数内的多重采样

Multiple sampling inside an R function

我正在尝试创建一个函数,最终会在我的数据集上 运行 多个机器学习算法。下面是我的函数的第一部分和一小部分数据样本。

我 运行 遇到的问题是将我的数据采样到四个不同的数据帧中,然后将它们应用于给定的函数。在第一个函数中,我正在测试数据 运行s 抛出了逻辑回归模型,但在输出中它使用了该模型的所有数据,而不是我想要的数据帧 df 的 1/4。我检查了 <<- 以查看正在传递的数据类型,它发送的数据集是我正在寻找的数据帧 df 的 1/4。问题为什么它会以正确的方式传递到我的全球环境而不是我的回归函数,我将如何纠正这个问题?

数据:

zeroFac <- c(1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1)

goal <- c(8.412055,  7.528869,  8.699681, 10.478752,  9.210440, 10.308986, 10.126671, 11.002117, 10.308986,  7.090910, 10.819798,  7.824446,  8.612685,
7.601402, 10.126671,  7.313887,  5.993961,  7.313887,  8.517393, 12.611541)

City_Pop <- c( 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613,
11.64613, 11.64613, 11.64613, 11.64613, 11.64613, 11.64613)

df <- data.frame(zeroFac,goal,City_Pop)

函数:

forestModel <- function(eq1, ...){

  #making our origenal data frame
  train <- data.frame(cbind(...))

  ################

    #splitting into 4 data sets
    set.seed(123)

    ss <- sample(1:4, size = nrow(train), replace=TRUE, prob = c(0.25,0.25,0.25,0.25))

    t1 <- train[ss==1,]
    t2 <- train[ss==2,]
    t3 <- train[ss==3,]
    t4 <- train[ss==4,]

  ################

  m <- glm(eq1, family = binomial(link = 'logit'), data = t1)
  summary(m)

}

eq1 <- df$zeroFac ~ df$goal + df$City_Pop


forestModel(eq1, df$zeroFac, df$goal, df$City_Pop)

train 中,列名不是您期望的("zeroFac"、"goal" 和 "City_Pop");它们是 "X1"、"X2" 和 "X3"。

根据glm的帮助,当公式中的变量在数据中没有时,取自environment(formula)。因此,它正在使用全球环境中的数据 - 创建公式的地方。

来自?glm

data an optional data frame, list or environment (or object coercible by as.data.frame to a data frame) containing the variables in the model. If not found in data, the variables are taken from environment(formula), typically the environment from which glm is called.

你的公式也不对。它应该是 eq1 <- zeroFac ~ goal + City_Pop 的形式。但是,仅纠正它并不能解决您的问题。

编辑

一个选项是单独传递变量的名称,如

forestModel <- function(eq1, colnam, ...) {

  train <- data.frame(cbind(...))
  colnames(train) <- colnam

  # splitting the data
  set.seed(123)

  ss <- sample(1:4, size = nrow(train), replace=TRUE, 
                    prob = c(0.25,0.25,0.25,0.25))

  t1 <- train[ss==1,]

  m <- glm(eq1, family = binomial(link = 'logit'), data = t1)
  summary(m)
}

eq1 <- zeroFac ~ goal + City_Pop
colnam <- c("zeroFac", "goal", "City_Pop")

forestModel(eq1, colnam, df$zeroFac, df$goal, df$City_Pop)

# Call:
#   glm(formula = eq1, family = binomial(link = "logit"), data = t1)
# 
# Deviance Residuals: 
#   2           4           5           8          11          16  
# 9.915e-06   2.110e-08  -1.080e-05  -2.110e-08   2.110e-08   2.110e-08  
# 20  
# 6.739e-06  
# 
# Coefficients:
#   Estimate Std. Error z value Pr(>|z|)
# (Intercept)    -960.87 2187192.38       0        1
# goal             12.32   41237.80       0        1
# City_Pop         74.28  166990.04       0        1
# 
# (Dispersion parameter for binomial family taken to be 1)
# Null deviance: 8.3758e+00  on 6  degrees of freedom
# Residual deviance: 2.6043e-10  on 4  degrees of freedom
# AIC: 6
# Number of Fisher Scoring iterations: 25

您必须更改公式并在函数中命名训练数据集的列。 等式从 eq1 <- df$zeroFac ~ df$goal + df$City_Pop 变为 eq1 <- zeroFac ~ goal + City_Pop。否则它还包含对数据框的调用,而不仅仅是对列名的调用。在将训练数据绑定在一起之后,您必须命名它们的列,因此 glm 函数知道您在等式中引用了哪些列。

 forestModel <- function(eq1, ...){

  #making our origenal data frame

  train <- data.frame(cbind(...))
  colNames <- colnames(data.frame(...))
  coln <- do.call(cbind, lapply(X = strsplit(colNames, "\."), FUN = function(X) X[[2]]))
  colnames(train) <- coln

  ################

  #splitting into 4 data sets
  set.seed(123)

  ss <- sample(1:4, size = nrow(train), replace=TRUE, prob = c(0.25,0.25,0.25,0.25))

  t1 <- train[ss==1,]
  ################

  m <- glm(eq1, family = binomial(link = 'logit'), data = t1)
  summary(m)
}

eq1 <- zeroFac ~ goal + City_Pop
forestModel(eq1, df$zeroFac, df$goal, df$City_Pop)