don*_*zao 28 r function dataframe
我使用R遇到了一个小问题......
在以下数据框中
test <- data.frame(v1=c(rep(1,3),rep(2,3)),v2=0)
Run Code Online (Sandbox Code Playgroud)
我想在v1为1的行中更改v2的值.
test[test$v1==1,"v2"] <- 10
Run Code Online (Sandbox Code Playgroud)
工作得很好.
test
v1 v2
1 1 10
2 1 10
3 1 10
4 2 0
5 2 0
6 2 0
Run Code Online (Sandbox Code Playgroud)
但是,我需要在函数中执行此操作.
test <- data.frame(v1=c(rep(1,3),rep(2,3)),v2=0)
test.fun <- function (x) {
test[test$v1==x,"v2"] <- 10
print(test)
}
Run Code Online (Sandbox Code Playgroud)
调用该函数似乎有效.
test.fun(1)
v1 v2
1 1 10
2 1 10
3 1 10
4 2 0
5 2 0
6 2 0
Run Code Online (Sandbox Code Playgroud)
但是,当我现在看看测试时:
test
v1 v2
1 1 0
2 1 0
3 1 0
4 2 0
5 2 0
6 2 0
Run Code Online (Sandbox Code Playgroud)
它不起作用.是否有命令告诉R真正更新函数中的数据框?非常感谢您的帮助!
Jos*_*ich 48
test
在你的函数中是来自你的全局环境的对象的副本(我假设它是在它定义的地方).转让发生在当前的环境下,除非另有规定,所以你需要告诉你想要的本地副本分配[R return(test)
到test
的test
.
将所有必需的对象作为参数传递给函数是一种很好的形式.
test.fun <- function (x, test) {
test[test$v1==x,"v2"] <- 10
return(test)
}
test <- data.frame(v1=c(rep(1,3),rep(2,3)),v2=0)
(test <- test.fun(1, test))
# v1 v2
#1 1 10
#2 1 10
#3 1 10
#4 2 0
#5 2 0
#6 2 0
Run Code Online (Sandbox Code Playgroud)
就个人而言,我会.GlobalEnv
在功能之外进行任务,但我不确定你是否可以在实际情况下这样做.
test.fun <- function (x, test) {
test[test$v1==x,"v2"] <- 10
assign('test',test,envir=.GlobalEnv)
#test <<- test # This also works, but the above is more explicit.
}
(test.fun(1, test))
# v1 v2
#1 1 10
#2 1 10
#3 1 10
#4 2 0
#5 2 0
#6 2 0
Run Code Online (Sandbox Code Playgroud)
小智 24
在你的函数中改变< - to << -也可以做到这一点,参见R-manual.从该页面引用:
运算符<< - 和 - >>通常仅在函数中使用,并且通过父环境搜索要分配的变量的现有定义.如果找到这样的变量(并且其绑定未被锁定),则重新定义其值,否则在全局环境中进行赋值.
那么你的代码应该是:
test <- data.frame(v1=c(rep(1,3),rep(2,3)),v2=0)
test.fun <- function (x) {
test[test$v1==x,"v2"] <<- 10
print(test)
}
test.fun(1)
Run Code Online (Sandbox Code Playgroud)
优良作法是不更改函数中的全局变量,因为这可能会产生不良副作用.为避免在R中出现这种情况,对函数内对象的任何更改实际上只会更改该函数的本地副本environment
.
如果你真的想要改变测试,你必须分配函数的返回值来测试(用更明确的返回值编写函数会更好,
test <- test.fun(1)
Run Code Online (Sandbox Code Playgroud)
或者选择要分配到的全局环境test.fun
,
test.fun <- function (x) {
test[test$v1==x,"v2"] <- 10
print(test)
assign("test",test,.GlobalEnv)
}
Run Code Online (Sandbox Code Playgroud)