如何更改数据框的名称

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 的每个值执行此操作,这就是dplyrgroup_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 与最初的提问者一样多或更多。我看到这个问题在您之前的编辑中遇到了问题,并想投入我的两分钱。

以上是关于如何更改数据框的名称的主要内容,如果未能解决你的问题,请参考以下文章

如何使用jquery更改与特定类匹配的所有文本框的属性

如何从 pyspark 数据框的模式属性(来自镶木地板文件)中获取特定字段名称的数据类型?

JSFL - 更改静态文本值

按名称切片数据框的列[重复]

如何使用 MySQL 更改数据库名称?

如何在实体框架中更改数据库名称