如何更改数据框的名称
Posted
技术标签:
【中文标题】如何更改数据框的名称【英文标题】:How can I change the name of a data frame 【发布时间】:2015-09-22 09:52:34 【问题描述】:我有一个经常出现的情况,我在一组长的 R 代码的顶部设置了一个值,该代码用于对一个或多个数据帧进行子集化。像这样的:
city_code <- "202"
在整个过程结束时,我想将结果保存在一个适当命名的数据框中,例如,基于将“city_code”附加到一个公共存根。
city_results <- paste("city_stats", city_code, sep = "")
我的问题是我不知道如何将结果数据框重命名为“city_results”的值。那里有很多关于如何重命名数据框列的信息,但没有关于如何重命名数据框本身的信息。根据建议的答案,这里有一个澄清:
谢谢,@mike-wise。有助于研究有具体问题的 Hadley 的 Advanced 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)
【问题讨论】:
嗨,约翰。我在回复中添加了一条评论来回答您的问题。 我知道这是旧的,但对于可能需要它的人来说,最后一行只需要head(get(gear_subset))
。 assign
的反义词是 get
。
次要点:paste("mtcars_", gear_code, sep = "") 可以稍微缩短为 paste0("mtcars_", gear_code)。 sep="" 选项的快捷方式。
【参考方案1】:
事实上,R 中的对象本身没有名称。存在不同类型的环境,包括每个进程的全局环境。这些环境具有指向各种对象的名称列表。两个不同的名称可以指向同一个对象。据我所知,这在 Hadley Wickhams Advanced R book 的环境章节中得到了最好的解释 http://adv-r.had.co.nz/Environments.html
所以没有办法更改数据框的名称,因为没有什么可更改的。
但是您可以让一个新名称(如newname
)指向与给定名称(如oldname
)相同的对象(在您的情况下为数据框对象):
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(...)
问题的各种 cmet,您可以像这样解析名称:
head(get(gear_subset))
【讨论】:
可能需要指定分配到的环境:assign(city_results, df, pos=1)
或assign(city_results, df, envir=.GlobalEnv)
谢谢@mike-wise。你已经回答了我的问题。 (我以前曾以食谱的方式使用过 parse,但现在我正在研究帮助文件。非常有帮助。:-)
eval(parse(...))
在您想要解析做某事的代码时很有用。对于简单地访问名称在字符串中的对象,get
是一个不错的快捷方式,例如,head(get(gear_subset))
而不是 `head(eval(parse(text = gear_subset)))
大多数时候你不需要 get
,如果你经常使用eval(parse(text = "..."))
,那么你真的做错了。
eval(parse(...))
在大多数情况下通常被认为是不好的做法,所以我不喜欢这样指点新手。参见,例如,fortunes::fortune(106)
和 fortunes::fortune(181)
,还有 What exactly are the dangers of eval(parse())
?,尽管讨论更多地集中在它的使用是实际上有保证的情况,而不是像这里有一个简单的替代方案.【参考方案2】:
通常,您不应该以编程方式为全局环境中的数据框生成名称。这很好地表明您应该使用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
的group_by
有帮助的地方:
所有齿轮的 CSV
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())
或get()
更简单。
【讨论】:
有点取决于确切的意图是什么,但是是的,这确实感觉就像它可能是什么。但是我不记得我在 2015 年 7 月编程了什么,我有点想知道 JDS 是否也能做到。 谁知道呢,但是对于浏览该网站的人来说,SO 与最初的提问者一样多或更多。我看到这个问题在您之前的编辑中遇到了问题,并想投入我的两分钱。以上是关于如何更改数据框的名称的主要内容,如果未能解决你的问题,请参考以下文章