我有一个包含train
(出生年份)列的数据框(称为YOB
)。我想在单独的列中计算Age
,如下所示:
train$Age = 2016 - train$YOB
这很好用。
问题是我还想对许多其他数据帧执行此操作(以及其他预处理操作)。所以,我正在考虑提取函数中的公共部分,并将要处理的数据帧作为参数传递给函数:
preprocess = function(d) {
d$Age = 2016 - d$YOB
# other transformations...
}
在定义上面的函数之后,我预计调用preprocess(train)
将在我的数据帧上执行上述转换。但它并没有。例如,调用后train$Age
为NULL
。
为什么preprocess
函数不按预期转换数据帧?有办法解决这个问题吗?
答案 0 :(得分:2)
在R(以及几乎所有语言)中,当控制转移到一个函数时,解释器设置一个"范围"其中的变量可以在函数中使用。
考虑变量a和b以及函数" preprocess":
> a <- 2
> b <- 3
> preprocess <- function(a){a <- a + b; cat("value of a=", a, "\n")}
> preprocess(a)
value of a= 5
> cat("value of a=", a, "\n")
value of a= 2
这里,变量&#34; a&#34;和&#34; b&#34;在函数内部都可以看到变量&#34; a&#34;确实在功能范围内发生了变化。 但是一旦函数完成并返回,该环境就被丢弃,变量的更新值被丢失&#34;。
之前为2的变量的全局值保持原样。
但是,如果你返回&#34; a&#34;的值从功能,&#34; a&#34;的价值已更改,请参阅此示例:
> a <- 2
> b <- 3
> preprocess <- function(a){a <- a + b; cat("value of a=", a, "\n"); return(a)}
> a <- preprocess(a)
value of a= 5
> cat("value of a=", a, "\n")
value of a= 5
有关详细信息,请参阅R会话?environment
中的此帮助参考。
答案 1 :(得分:1)
只在函数内部添加新列,但函数通常不会更改该函数之外的值。通过&lt;&lt; - 快速而肮脏的方式 - 但是真的不应该使用它!因为你的函数会改变函数之外的值,函数不应该这样做。这是非常糟糕的风格。值应该作为参数输入函数,并应将它们作为返回值。
因此,请更改函数中的数据框并将其作为返回值返回:
preprocess = function(d) {
d$Age = 2016 - d$YOB
return(d)
}
test <- data.frame(YOB=2017:2020)
test <- preprocess(test)
print(test)