【问题标题】:test for existing row.names and col.names in data.frame测试 data.frame 中现有的 row.names 和 col.names
【发布时间】:2015-04-30 20:58:00
【问题描述】:

是否有一个函数可以确定 data.frame 是否具有本机行名和列名或仅具有自动生成的 (1 2 3 4...) ?对于列名,“自动”意味着例如当您将“as.data.frame”应用于矩阵时..

对于行名,我想出了一个解决方法:

has.row.names = function(df) {
  !all(row.names(df)==seq(1, nrow(df)))
}

但是,对于列名,我不知道该怎么做。困难在于有时自动 col.names 以 V1 V2 等开头,有时以 X1.、X2.. 开头。

编辑:为什么我会问这个问题:我需要在一个更复杂的函数(有点类似于 PCA 的图形输出)中执行这个测试,该函数将绘制行名和列名,如果现有的,如果没有,它将创建更合适的新名称。 所以它应该适用于“任何”data.frame,没有实际名称的线索..

谢谢。

【问题讨论】:

  • 目的是什么?你真的会根据它是否自动生成而做一些不同的事情吗?它需要在任何数据框上工作吗?如果只是用 read.table 创建的,那么更精确地使用 read.table 可能会告诉你。
  • 是的,需要适用于任何 df。这就是为什么我事先不知道他们。而且我不想要自动生成的列名和行名,这对情节来说会一团糟。
  • tibble 包中的函数 has_rownames 现在可以处理行名

标签: r dataframe attributes rowname


【解决方案1】:
#Use exists
with(mtcars,exists("cyl"))
[1] TRUE

with(mtcars,exists("cy"))
[1] FALSE

【讨论】:

  • 感谢我不知道的“存在”功能。但它需要自动化,我事先不知道名称。
  • 对于tab1中的每个col,测试是否在tab2中找到它:cn <- colnames(tab1); sapply(cn, function(x) { with(tab2, exists(x))});
  • 更简单:missingCols <- setdiff(colnames(tab1), colnames(tab2))
【解决方案2】:

简短版: 数据框唯一没有列名的情况是属性“names”为 NULL。因此,检查数据框中是否存在列名的简单方法如下所示。

DFHasColNames <- function(x) {
    stopifnot(is.data.frame(x))
    Negate(is.null)(names(x))
}
DFHasColNames(mtcars)
# [1] TRUE
DFHasColNames(unname(mtcars))
# [1] FALSE

扩展版:对于行名,您可以使用.row_names_info()。使用默认的type = 1L,负号表示行名是自动生成的。

.row_names_info(mtcars)
# [1] 32   # row names were provided 
.row_names_info(iris)
# [1] -150 # row names were generated automatically

您还可以通过更改type 参数来查看其他信息。

类型整数。当前 type = 0 返回内部的“row.names”属性(可能为 NULL),type = 2 是该属性隐含的行数,type = 1 后者带有负号表示“自动”行名。

.row_names_info(mtcars, type = 0)
## ... returns attr(mtcars, "row.names")
.row_names_info(iris, type = 0)
## [1]   NA -150

对于列名,这并不容易。一般来说,如果您看到列名的所有NA 值,或者names(x) 返回NULL,则未设置x 的“名称”属性,因此x 没有(列)名称。

否则,前缀X通常表示名称来自make.names(),由data.frame()read.table()read.csv()等使用。

m <- matrix(1:6, 2)
make.names(seq_len(ncol(m)))
# [1] "X1" "X2" "X3"
data.frame(m)
#   X1 X2 X3
# 1  1  3  5
# 2  2  4  6

而您通常会从 as.data.frame() 获得前置的 V

as.data.frame(m)
#   V1 V2 V3
# 1  1  3  5
# 2  2  4  6

但是,这不是规则。这取决于您传递给as.data.frame() 的对象的类,以及您是否更改了任何默认参数。最好的办法是从众多methods(as.data.frame) 中筛选,看看您是否能发现其中的规律。

【讨论】:

  • .row_names_info(x)返回0是什么意思?不幸的是,它没有记录在案……
  • @KonradRudolph - 不确定,但我认为这意味着数据没有开始的行。见.row_names_info(data.frame()),它返回0。
  • 不,数据(矩阵)有行和行名。我的问题是这显然搞砸了tibble::as_tibble;如果我正确阅读了它的代码,它应该在转换之前对矩阵的行名做一些事情,但它只是删除它们,并且通过跟踪代码我发现了上述问题。
猜你喜欢
  • 1970-01-01
  • 2018-11-11
  • 2022-07-20
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-20
  • 1970-01-01
相关资源
最近更新 更多