在R中编写函数

3

我在通过使用SAS多年后开始学习R,很快发现R中的函数与SAS中的宏不同,因此需要一些指导。

以下是我编写的无法运行的函数:

dscore<-function(data,var){

  ave<-mean(data$var)
  sd<-sd(data$var)

  data$vardscore<-(data$var-ave)/sd


  return(data)
}

我正在使用汽车数据集

cars<-dscore(cars,speed)

应该返回一个带有额外列的汽车数据框,该列是该观察值速度变量的Cohen D值。
我遇到了各种各样的错误,所以我会感激任何帮助。
编辑:
dbind<-function(data,var){
  var<-substitute(var)
  var<-as.character(var)
  ave<-mean(data[,var])
  sd<-sd(data[,var])
  name<-paste0(var,"dscore")
  data$name=((data[,var]-ave)/sd)
  return(data)
}

我需要帮助根据输入动态命名新列。目前只能得到一个名为“name”的新列。


1
需要记住的重要一点是,SAS函数基于文本替换,因此在这种情况下data$var被翻译为cars$speed是有意义的。另一方面,R则不同,它会传递一个表示为datacars副本,但实际上会查找data$var - 而这个变量在从cars复制的数据集中当然不存在。 - thelatemail
实际的列名在传递给函数时应该只是字符面量,除非你确实想让它们被计算。这并不是说函数不像宏一样运行(虽然这也是真的),但至少在这种情况下是参数被计算了。解释器在调用环境中查找名为“speed”的变量,但没有找到它。(同时在函数内部使用"$"通常不是个好主意,如果你学会使用"[",那么你会更加愉快) - IRTFM
顺便提一下,您也可以仅将必要的内容传递给函数。对于您的示例:dscore <- function(x) (x-mean(x))/sd(x),然后执行 cars$vardscore <- dscore(cars$speed)cars["vardscore"] <- dscore(cars[,"speed"]) - thelatemail
不要试图一次做所有事情 - 使用我上面评论中的 dscore 函数,然后可以执行:cars[paste(names(cars),"dscore",sep=".")] <- lapply(cars, dscore) 这样一切问题都解决了。 - thelatemail
@Pascal - 确实如此 - 但我假设这是一个简化的例子,用于讨论的重点。将上面的 dscore 替换为 scale,你也可以开始工作了。 - thelatemail
显示剩余2条评论
2个回答

4
您不能使用 $ 符号与变量一起使用。请尝试改为:
data[,var]

其中var必须是一个字符,例如"speed"

dscore<-function(data,var){

  ave<-mean(data[,var])
  sd<-sd(data[,var])

  data[,paste0(var,"dscore")]<-(data[,var]-ave)/sd


  return(data)
}

cars<-dscore(cars,var="speed")

谢谢,我现在的问题是正在添加的列名为vardscore而不是speeddscore,因此我需要帮助根据输入动态命名新列。 - Carl
1
@CarlGanz 同样的反馈,使用[,代替$ - RockScience

3
dscore<-function(data,var){
  ave<-mean(data[,var])
  sd<-sd(data[,var])
  data$vardscore<-(data[,var]-ave)/sd
  return(data)
}
cars<-dscore(cars, "speed")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接