【问题标题】:variable scope & resolution in R functionR函数中的变量范围和分辨率
【发布时间】:2013-12-04 03:47:43
【问题描述】:

我想遍历数据帧中的变量,在每个变量上调用 lm(),所以我写了这个:

findvars <- function(x = samsungData, dv = 'activity', id = 'subject') {
  # Loops through the possible predictor vars, does an lm() predicting the dv
  # from each, and returns a data.frame of coefficients, one row per IV.
  r <- data.frame()
  # All varnames apart from the dependent var, and the case identifier
  ivs <- setdiff(names(x), c(dv, id))
  for (iv in ivs) {
    print(paste("trying", iv))
    m <- lm(dv ~ iv, data = x, na.rm = TRUE)
    # Take the absolute value of the coefficient, then transpose.
    c <- t(as.data.frame(sapply(m$coefficients, abs)))
    c$iv <- iv # which IV produced this row?
    r <- c(r, c)
  }
  return(r)
}

这不起作用,我相信 b/c lm() 调用中的公式由函数局部变量组成,这些变量在传入的数据帧中保存字符串命名变量(例如,“my_dependant_var”和“this_iv”)而不是指向实际变量对象的指针。

我尝试将该公式包装在 eval(parse(text = )) 中,但无法使其工作。

如果我的问题是正确的,有人可以向我解释如何让 R 将这些 vars iv & dv 的内容解析为我需要的指针吗?或者如果我错了,有人可以解释一下发生了什么吗?

非常感谢!

这是一些重现代码:

library(datasets)
data(USJudgeRatings)
findvars(x = USJudgeRatings, dv = 'CONT', id = 'DILG')

【问题讨论】:

  • ?reformulate(您可以搜索该关键字)
  • 在 R 中你应该忘记“指向对象的指针”。值被传递......作为值。而公式中的“变量”并不是真正的“字符串”。名称和符号是超类“语言”的对象。字符向量不是。

标签: r


【解决方案1】:

因此,除了公式出现问题之外,您的函数中发生了足够多的坏事,我认为应该有人指导您完成这一切。下面是一些注释,后面是更好的版本:

  #For small examples, "growing" objects isn't a huge deal,
  # but you will regret it very, very quickly. It's a bad
  # habit. Learn to ditch it now. So don't inititalize
  # empty lists and data frames.
  r <- data.frame()

  ivs <- setdiff(names(x), c(dv, id))
  for (iv in ivs) {
    print(paste("trying", iv))
    #There is no na.rm argument to lm, only na.action
    m <- lm(dv ~ iv, data = x, na.rm = TRUE)
    #Best not to name variables c, its a common function, see two lines from now!
    # Also, use the coef() extractor functions, not $. That way, if/when
    # authors change the object structure your code won't break.
    #Finally, abs is vectorized, no need for sapply
    c <- t(as.data.frame(sapply(m$coefficients, abs)))
    #This is probably best stored in the name
    c$iv <- iv # which IV produced this row?
    #Growing objects == bad! Also, are you sure you know what happens when
    # you concatenate two data frames?
    r <- c(r, c)
  }
  return(r)
}

试试这样的:

findvars <- function(x,dv,id){
  ivs <- setdiff(names(x),c(dv,id))
  #initialize result list of the appropriate length
  result <- setNames(vector("list",length(ivs)),ivs)
  for (i in seq_along(ivs)){
    result[[i]] <- abs(coef(lm(paste(dv,ivs[i],sep = "~"),data = x,na.action = na.omit)))
  }
  result
}

【讨论】:

  • 天哪——非常感谢你打破了这一切!这当然有效,而且我知道它为什么有效——至少我是这么认为的。我很高兴知道 lm() 将为公式参数使用一个字符串——我想我的问题的一部分是将我的 paste() 调用包装在 eval() 中?或者其他的东西。无论如何——感谢您在时间上如此慷慨!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-25
  • 2022-08-03
相关资源
最近更新 更多