我有一种经常出现的情况,我在一组R代码的顶部设置了一个值,该代码用于对一个或多个数据帧进行子集化。像这样:
city_code <- "202"
在整个过程结束时,我想将结果保存在一个相应命名的数据框中,比如说,基于附加&#34; city_code&#34;一个共同的存根。
city_results <- paste("city_stats", city_code, sep = "")
我的问题是,我无法弄清楚如何将结果数据框重命名为&#39; city_results&#39;的值。有很多关于如何重命名数据框列的信息,但没有关于如何重命名数据框本身的信息。根据提议的答案,这里有一个澄清:
谢谢,@迈克明智。有助于学习哈德利的高级R,手头有一个具体的问题。
library(dplyr)
gear_code <- 4
gear_subset <- paste("mtcars_", gear_code, sep = "")
mtcars_subset <- mtcars %>% filter(gear == gear_code)
head(mtcars_subset)
write.csv(mtcars_subset, file = paste(gear_subset, ".csv", sep = ""))
这让我可以将子集写入适当命名的csv文件。但是,您的建议有点有效,但我不能用新名称引用data.frame:
assign(gear_subset, mtcars_subset)
head(gear_subset)
答案 0 :(得分:13)
事实是R中的对象本身没有名称。存在不同类型的环境,包括用于每个过程的全局环境。这些环境具有名称列表,指向各种对象。两个不同的名称可以指向同一个对象。根据我对Hadley Wickhams Advanced R书籍环境章节的了解,这是最好的解释 http://adv-r.had.co.nz/Environments.html
因此无法更改数据框的名称,因为无需更改任何内容。
但是您可以通过执行以下操作,使新名称(如newname
)指向同一对象(在您的情况下为数据框对象)作为给定名称(如oldname
): p>
newname <- oldname
请注意,如果更改其中一个变量,则会生成新副本,并且内部引用将不再相同。这是由于R的“复制修改”语义。请参阅此帖子以获取解释:What exactly is copy-on-modify semantics in R, and where is the canonical source?
希望有所帮助。我知道痛苦。动态和函数语言与静态和过程语言不同......
当然可以计算数据帧的新名称并使用assign
命令在环境中注册 - 也许您正在寻找这个。然而,事后提到它会相当复杂。
示例(假设df
是有问题的数据框):
assign( paste("city_stats", city_code, sep = ""), df )
始终查看assign
的帮助以获取更多信息http://stat.ethz.ch/R-manual/R-devel/library/base/html/assign.html
编辑:
在回复您的编辑以及有关使用eval(parse(...)
的问题的各种评论时,您可以像这样解析名称:
head(get(gear_subset))
答案 1 :(得分:1)
通常,不应以编程方式为全局环境中的数据框生成名称。这表明您应该使用list
来简化您的生活。有关许多示例和更多讨论,请参阅常见问题解答How to make a list of data frames?。
使用你的具体例子,我会用几种不同的方式重写它。
library(dplyr)
gear_code <- 4
gear_subset <- paste("mtcars_", gear_code, sep = "")
mtcars_subset <- mtcars %>% filter(gear == gear_code)
head(mtcars_subset)
write.csv(mtcars_subset, file = paste(gear_subset, ".csv", sep = ""))
目标似乎是编写一个名为gear_X.csv
的CSV,其mtcars
子集带有gear == X
。你不要保留一个中间数据框,这应该没问题:
gear_code <- 4
mtcars %>% filter(gear == gear_code) %>%
write.csv(file = paste0('mtcars_', gear_code, '.csv'))
但是,您可能正是以这种方式对其进行编码,因为您希望为gear
的每个值执行此操作,这是dplyr
的{{1}}帮助的地方:
group_by
如果你真的想要每个齿轮级别的单个数据框架对象,那么将它们保存在列表中是可行的。
mtcars %>% group_by(gear) %>%
do(csv = write.csv(file = sprintf("mt_gear_%s.csv", .[1, "gear"]), x = .)
这会为您提供三个数据框gear_df = split(mtcars, mtcars$gear)
,每个list
级别一个。并且它们已经以级别命名,因此要查看包含所有gear
行的数据框,请执行
gear == 4
通常,这比使用的三个数据框更容易使用。您想要使用单个gear_df[["4"]]
同时对所有数据框执行的操作,即使您要使用lapply
循环,也比for
或eval(parse())
。