如何在R中创建,构建,维护和更新数据码本?

时间:2011-03-17 00:03:02

标签: r metadata data-management

为了复制,我喜欢为每个数据帧保留一个带有元数据的码本。数据码本是:

  

书面或计算机化列表,提供将包含在数据库中的变量的清晰而全面的描述。 Marczyk等人2010

我想记录变量的以下属性:

  
      
  • 名称
  •   
  • 描述(标签,格式,比例等)
  •   
  • 来源(例如世界银行)
  •   
  • 源媒体(访问的网址和日期,CD和ISBN,或其他)
  •   
  • 磁盘上源数据的文件名(合并代码簿时有帮助)
  •   
  • 注释
  •   

例如,我正在实现这一目标,用8个变量记录数据框 mydata1 中的变量:

code.book.mydata1 <- data.frame(variable.name=c(names(mydata1)),
     label=c("Label 1",
              "State name",
              "Personal identifier",
              "Income per capita, thousand of US$, constant year 2000 prices",
              "Unique id",
              "Calendar year",
              "blah",
              "bah"),
      source=rep("unknown",length(mydata1)),
      source_media=rep("unknown",length(mydata1)),
      filename = rep("unknown",length(mydata1)),
      notes = rep("unknown",length(mydata1))
)

我为每个读过的数据集写了不同的代码簿。当我合并数据帧时,我还将合并其相关代码簿的相关方面,以记录最终数据库。我这样做主要是复制粘贴上面的代码并更改参数。

5 个答案:

答案 0 :(得分:7)

您可以使用attr函数向任何R对象添加任何特殊属性。 E.g:

x <- cars
attr(x,"source") <- "Ezekiel, M. (1930) _Methods of Correlation Analysis_.  Wiley."

并查看对象结构中的给定属性:

> str(x)
'data.frame':   50 obs. of  2 variables:
 $ speed: num  4 4 7 7 8 9 10 10 10 11 ...
 $ dist : num  2 10 4 22 16 10 18 26 34 17 ...
 - attr(*, "source")= chr "Ezekiel, M. (1930) _Methods of Correlation Analysis_.  Wiley."

并且还可以使用相同的attr函数加载指定的属性:

> attr(x, "source")
[1] "Ezekiel, M. (1930) _Methods of Correlation Analysis_.  Wiley."

如果只向数据框添加新案例,则给定属性不会受到影响(请参阅:str(rbind(x,x)),而更改结构将会增加给定属性(请参阅:str(cbind(x,x)))。


根据评论更新

如果要列出所有非标准属性,请检查以下内容:

setdiff(names(attributes(x)),c("names","row.names","class"))

这将列出所有非标准属性(标准是:名称,行名,数据框中的类)。

基于此,您可以编写一个简短的函数来列出所有非标准属性以及值。以下确实有效,但不是很整齐......你可以改进它并组成一个函数:)

首先,定义uniqe(=非标准)属性:

uniqueattrs <- setdiff(names(attributes(x)),c("names","row.names","class"))

制作一个包含名称和值的矩阵:

attribs <- matrix(0,0,2)

循环遍历非标准属性并在矩阵中保存名称和值:

for (i in 1:length(uniqueattrs)) {
    attribs <- rbind(attribs, c(uniqueattrs[i], attr(x,uniqueattrs[i])))
}

将矩阵转换为数据框并命名列:

attribs <- as.data.frame(attribs)
names(attribs) <- c('name', 'value')

以任何格式保存,例如:

write.csv(attribs, 'foo.csv')

关于变量标签的问题,请检查包 foreign 中的read.spss函数,因为它完全符合您的需要:将值标签保存在attrs部分。主要思想是attr可以是数据框或其他对象,因此您不需要为每个变量创建唯一的“attr”,而只需要创建一个(例如命名为“varable标签”)并将所有信息保存在那里。您可以调用:attr(x, "variable.labels")['foo']其中'foo'代表所需的变量名称。但请查看上面引用的函数以及导入的数据框的属性以获取更多详细信息。

我希望这些可以帮助你以比我上面尝试的更简洁的方式编写所需的功能! :)

答案 1 :(得分:5)

更高级的版本是使用S4类。例如,在生物传导器中,ExpressionSet用于存储具有其相关实验元数据的微阵列数据。

Section 4.4中描述的MIAME对象看起来非常类似于你所追求的:

experimentData <- new("MIAME", name = "Pierre Fermat",
          lab = "Francis Galton Lab", contact = "pfermat@lab.not.exist",
          title = "Smoking-Cancer Experiment", abstract = "An example ExpressionSet",
          url = "www.lab.not.exist", other = list(notes = "Created from text files"))

答案 2 :(得分:4)

此处comment()功能可能很有用。它可以设置和查询对象的注释属性,但具有其他不打印的常规属性的优点。

dat <- data.frame(A = 1:5, B = 1:5, C = 1:5)
comment(dat$A) <- "Label 1"
comment(dat$B) <- "Label 2"
comment(dat$C) <- "Label 3"
comment(dat) <- "data source is, sampled on 1-Jan-2011"

给出:

> dat
  A B C
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
> dat$A
[1] 1 2 3 4 5
> comment(dat$A)
[1] "Label 1"
> comment(dat)
[1] "data source is, sampled on 1-Jan-2011"

合并示例:

> dat2 <- data.frame(D = 1:5)
> comment(dat2$D) <- "Label 4"
> dat3 <- cbind(dat, dat2)
> comment(dat3$D)
[1] "Label 4"

但是对dat()

的评论失去了意见
> comment(dat3)
NULL

所以这些操作需要明确处理。要真正做到你想要的,你可能需要编写你使用的特殊版本的函数来维护提取/合并操作期间的注释/元数据。或者,您可能希望研究生成自己的对象类 - 例如,包含数据框的列表和包含元数据的其他组件。然后编写所需函数的方法来保存元数据。

这些行的一个例子是zoo包,它为一个时间序列生成一个列表对象,其中包含保存排序和时间/日期信息等的额外组件,但是从子集等的角度来看仍然像普通对象一样工作,因为作者为[等函数提供了方法。

答案 3 :(得分:4)

从2020年开始,有一些R包直接专用于可能满足您需求的代码本。

答案 4 :(得分:3)

我如何做到这一点有点不同,而且技术性显着降低。我通常遵循以下指导原则:如果文本不是设计为对计算机有意义并且仅对人类有意义,则它属于源代码中的注释。

这可能感觉相当“低技术”,但有一些很好的理由这样做:

  • 当其他人将来拿起您的代码时,直观的评论是明确的,供他们阅读。在数据结构中的不寻常位置设置的参数对于将来的用户可能并不明显。
  • 跟踪抽象对象内部设置的参数需要相当多的纪律。创建代码注释也需要遵守纪律,但是注释的缺失立即显而易见。如果描述作为对象的一部分被携带,那么浏览代码并不会使这一点变得明显。然后,代码在“文字编程”意义上变得不那么“有文化”。
  • 对数据对象内部的数据进行描述很容易导致描述不正确。例如,如果将包含以kg为单位的测量值的列乘以2.2以将单位转换为磅,则会发生这种情况。忽略更新元数据的需要将非常容易。

显然,携带元数据和对象有一些真正的好处。如果您的工作流程使上述要点不那么密切,那么为数据结构创建元数据附件可能会很有意义。我的意图只是分享为什么可以考虑采用“低技术”评论的方法。