在最近与同学的对话中,我一直主张避免全局,除了存储常量.这是一种典型的应用统计类型程序,每个人编写自己的代码和项目大小都很小,所以人们很难看到由于草率的习惯造成的麻烦.
在谈论避免使用全局变量时,我主要关注全局变量可能导致问题的以下原因,但我想在R和/或Stata中使用一些示例来遵循原则(以及您可能认为重要的任何其他原则) ),我很难想出可信的人.
对这个问题的一个有用的答案是一个可重现的,自包含的代码片段,其中全局变量会导致特定类型的麻烦,理想情况下是另一个代码片段,其中问题得到纠正.如有必要,我可以生成更正的解决方案,因此问题的示例更为重要.
相关链接:
昨天我从Bill Venables那里了解到local()如何帮助创建静态函数和变量,例如,
example <- local({
hidden.x <- "You can't see me!"
hidden.fn <- function(){
cat("\"hidden.fn()\"")
}
function(){
cat("You can see and call example()\n")
cat("but you can't see hidden.x\n")
cat("and you can't call ")
hidden.fn()
cat("\n")
}
})
Run Code Online (Sandbox Code Playgroud)
从命令提示符的行为如下:
> ls()
[1] "example"
> example()
You can see and call example()
but you can't see hidden.x
and you can't call "hidden.fn()"
> hidden.x
Error: object 'hidden.x' not found
> hidden.fn()
Error: could not find function "hidden.fn"
Run Code Online (Sandbox Code Playgroud)
我跟着这里的讨论,很好奇为什么<<-在R中使用它不赞成它会引起什么样的混乱?
我也想要一些关于如何避免的提示<<-.我经常使用以下内容.例如:
### Create dummy data frame of 10 x 10 integer matrix.
### Each cell contains a number that is between 1 to 6.
df <- do.call("rbind", lapply(1:10, function(i) sample(1:6, 10, replace = TRUE)))
Run Code Online (Sandbox Code Playgroud)
我想要实现的是将每个数字减少1,即所有2s将变为1,所有3将变为2等等.因此,一切n都会到来n-1.我通过以下方式实现这一目标:
df.rescaled <- df
sapply(2:6, function(i) df.rescaled[df.rescaled == i] <<- i-1))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我该如何避免<<-?理想情况下,我希望能够将sapply结果传递到另一个变量:
df.rescaled <- sapply(...)
Run Code Online (Sandbox Code Playgroud) 我试图把我的脑袋缠在一起,我想我已经找到了一个他们可能会有所帮助的案例.
我有以下几件可供使用:
这个想法是,给定一些带有草率国家名称的数据框架(资本列为"华盛顿特区","华盛顿特区","哥伦比亚特区"等)?,让一个函数返回相同的数据删除了状态名称列的.frame,仅剩下状态ID代码.然后,后续合并可以一致地发生.
我可以通过多种方式实现这一点,但是一种似乎特别优雅的方法是将合并映射和正则表达式以及代码处理闭包内的所有内容(遵循闭包是一个带数据的函数的想法) ).
问题1:这是一个合理的想法吗?
问题2:如果是这样,我该怎么做R?
这是一个愚蠢的简单干净状态名称函数,适用于示例数据:
cleanStateNames <- function(x) {
x <- tolower(x)
x[grepl("columbia",x)] <- "DC"
x
}
Run Code Online (Sandbox Code Playgroud)
以下是将运行最终函数的一些示例数据:
dat <- structure(list(state = c("Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut", "Delaware", "District of Columbia",
"Florida"), pop08 = structure(c(29L, 44L, 40L, 18L, 25L, 30L,
22L, 48L, 36L, 13L), .Label = c("1,050,788", "1,288,198", "1,315,809",
"1,316,456", "1,523,816", "1,783,432", "1,814,468", "1,984,356",
"10,003,422", "11,485,910", "12,448,279", "12,901,563", "18,328,340",
"19,490,297", "2,600,167", "2,736,424", "2,802,134", "2,855,390",
"2,938,618", "24,326,974", "3,002,555", "3,501,252", "3,642,361",
"3,790,060", "36,756,666", …Run Code Online (Sandbox Code Playgroud)