如何将元数据添加到 tibble

Posted

技术标签:

【中文标题】如何将元数据添加到 tibble【英文标题】:How to add metadata to a tibble 【发布时间】:2018-06-17 20:10:55 【问题描述】:

我想要一个描述我的每个变量名称的句子,这样我就可以打印出带有相关元数据的 tibble,如果我把它交给以前没有看过数据的人,他们就能理解它。

as_tibble(iris)

# A tibble: 150 × 5
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          <dbl>       <dbl>        <dbl>       <dbl>  <fctr>
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
3           4.7         3.2          1.3         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa
5           5.0         3.6          1.4         0.2  setosa
6           5.4         3.9          1.7         0.4  setosa
7           4.6         3.4          1.4         0.3  setosa
8           5.0         3.4          1.5         0.2  setosa
9           4.4         2.9          1.4         0.2  setosa
10          4.9         3.1          1.5         0.1  setosa
# ... with 140 more rows

# Sepal.length. Measured from sepal attachment to stem
# Sepal.width. Measured at the widest point
# Petal.length. Measured from petal attachment to stem
# Petal.width. Measured at widest point
# Species. Nomenclature based on Integrated Taxonomic Information System (ITIS), January 2018.

谢谢!

【问题讨论】:

?comment 可能就是您要找的东西 【参考方案1】:

这似乎很棘手。原则上@hrbrmstr 的注释是可行的方法(即使用?comment?attr 为任何对象添加属性),但这些属性默认情况下不会打印出来atomic 对象的属性似乎是自动打印的:

> z <- 1:6
> attr(z,"hello") <- "goodbye"
> z
[1] 1 2 3 4 5 6
attr(,"hello")
[1] "goodbye"

...但不是,唉,对于数据帧或小标题:

dd <- tibble::tibble(x=1:4,y=2:5)
> attr(dd,"metadata") <- c("some stuff","some more stuff")
> dd
# A tibble: 4 x 2
      x     y
  <int> <int>
1     1     2
2     2     3
3     3     4
4     4     5

你可以用它自己的 S3 类包装对象来打印这些东西:

class(dd) <- c("my_tbl",class(dd))
> print.my_tbl <- function(x) 
+    NextMethod(x)
+    print(attr(x,"metadata"))
+    invisible(x)
+ 
> dd
# A tibble: 4 x 2
      x     y
  <int> <int>
1     1     2
2     2     3
3     3     4
4     4     5
[1] "some stuff"      "some more stuff"

您可以使打印更精致或更漂亮,例如

cat("\nMETADATA:\n")
cat(sprintf("# %s",attr(x,"metadata")),sep="\n")

如果其他用户没有定义print.my_tbl(打印方法将回退到小标题的打印方法),不会发生任何不好的事情,但只有当他们有您的print.my_tbl 定义时才会打印元数据。 .

【讨论】:

这对 Ben 很有帮助。有没有办法做类似的事情,但只会在从 RDS 文件加载表时打印属性? 这看起来确实很棘手。对象的 print 方法很难知道该对象是刚刚加载还是已经在会话中一段时间​​。我能想到的最简单的管理方法是(1)将“print_attributes”作为参数添加到print.my_tbl(默认为 FALSE); (2) 编写一个专用的read_my_tbl() 函数,调用x &lt;- readRDS(...)print(x, print_attributes=TRUE),然后返回invisible(x)(这样对象就不会再次打印了。 谢谢本。我有同样的想法,目前正在使用自定义读取功能。很高兴知道至少没有更简单的解决方案!【参考方案2】:

这与 Ben Bolker 的建议并没有什么不同,但从概念上讲,如果我希望信息与数据框中的向量相关,我希望它们直接与向量相关联。换句话说,我更愿意将属性添加到向量本身而不是数据框对象。

我不知道我是否会向对象添加自定义类,但也许您可以为类似数据框的对象调用一个单独的函数就足够了:

library(tibble)
library(ggplot2)
library(magrittr)
library(labelVector)

print_with_label <- function(dframe)
  stopifnot(inherits(dframe, "data.frame"))
  labs <- labelVector::get_label(dframe, names(dframe))
  labs <- sprintf("%s: %s", names(dframe), labs)
  print(dframe)
  cat("\n")
  cat(labs, sep = "\n")


iris <- 
  as_tibble(iris) %>%  
  set_label(Sepal.Length = "This is a user friendly label",
            Petal.Length = "I much prefer reading human over computer")

print_with_label(iris)

mtcars <-
  set_label(mtcars,
            mpg = "Miles per Gallon",
            qsec = "Quarter mile time",
            hp = "Horsepower",
            cyl = "Cylinders",
            disp = "Engine displacement")

print_with_label(mtcars)

【讨论】:

【参考方案3】:

抱歉,回复延迟。但是自从我第一次开始学习 R 以来,这个话题就一直困扰着我。在我的工作中,将元数据分配给列并不常见。这是必需的。 R 似乎没有一个很好的方法来做到这一点,这真的让我很困扰。如此之多,以至于我写了一些包来做到这一点。

fmtr 包具有分配描述(以及其他内容)的功能。并且libr 包有一个字典功能,所以你可以查看你分配的所有元数据。

这是它的工作原理:

首先,将描述分配给列。您只需将命名列表发送到 descriptions() 函数。

library(fmtr)
library(libr)

# Create data frame
df <- iris

# Assign descriptions
descriptions(df) <- list(Sepal.Length = "Measured from sepal attachment to stem", 
                         Sepal.Width = "Measured at the widest point",
                         Petal.Length = "Measured from petal attachment to stem", 
                         Petal.Width = "Measured at the widest point",
                         Species = paste("Nomanclature based on Integrated Taxonomic", 
                                         "Information System (ITIS), January 2018."))


然后调用dictionary()函数就可以看到所有的元数据了,像这样:

dictionary(df)
# # A tibble: 5 x 10
#  Name  Column      Class  Label Description                                                 
#  <chr> <chr>       <chr>  <chr> <chr>                                                      
# 1 df    Sepal.Leng~ numer~ NA    Measured from sepal attachment to stem                     
# 2 df    Sepal.Width numer~ NA    Measured at the widest point                                
# 3 df    Petal.Leng~ numer~ NA    Measured from petal attachment to stem                      
# 4 df    Petal.Width numer~ NA    Measured at the widest point                                 
# 5 df    Species     factor NA    Nomanclature based on Integrated Taxonomic Information Syst~

如果您愿意,可以将字典作为自己的数据框返回,然后保存或打印或其他方式。

d <- dictionary(df)

这里是字典数据框:

【讨论】:

以上是关于如何将元数据添加到 tibble的主要内容,如果未能解决你的问题,请参考以下文章

将元数据添加到 CSV 文件中以指示 Excel 应如何打开

使用 Laravel 5.0 存储门面将元数据、标头(Expires、CacheControl)添加到上传到 Amazon S3 的文件中

Stripe:在创建时将元数据添加到订阅

matplotlib 可以将元数据添加到保存的图形中吗?

使用 @solana/web3.js 将元数据添加到 Solana 令牌

将元数据添加到RESTful JSON响应的最佳做法是什么?