首页 > 解决方案 > “字典”列表到 data.table 列

问题描述

我正在将 API 调用的输出转换为参考书目数据库,该数据库以 RIS 形式返回内容。然后我想获得一个 data.table 对象,每个数据库项都有一行,RIS 输出的每个字段都有一个列。

稍后我将解释更多关于 RIS 的信息,但我陷入了以下困境:

我想得到一个 data.table 使用类似的东西:

PubDB <- as.data.table(list(TY = "txtTY",TI = "txtTI"))

返回:

PubDB

      TY    TI
1: txtTY txtTI

但是,我拥有的是一个字符串(实际上是从 API 调用返回的字符串向量:PubStr 是一个元素)

PubStr

## [1] "TY = \"txtTY\",TI = \"txtTI\" "

如何将此字符串转换为上面 as.data.table 命令中所需的列表?

更具体地说,在我的代码的第一步之后,resp<-GET(url)在一些字符串操作之后,我有一个数据表,其中包含每个出版物的行,并且一个名为的列具有上述字符串。对于 data.table 的每一行,如何将此字符串转换为多列。注意:有些行有更多或更少的字段。rawToChar(resp$content)as.data.table()PubStr

标签: rstringdata.table

解决方案


我不确定 RIS 格式,但如果这些字符串的每个元素都用逗号分隔,然后在每个逗号内,标题列名称用等号分隔,那么这里是一个使用基本 R 和 data.table 的快速而肮脏的函数:

RIS_parser_fn<-function(x){

string_parse_list<-lapply(lapply(x,
                                 function(i) tstrsplit(i,",")),
                          function(j) lapply(tstrsplit(j,"="),
                                            function(k) t(gsub("\\W","",k))))

datatable_format<-rbindlist(lapply(lapply(string_parse_list,
                                          function(i) data.table(Reduce("rbind",i))),
                                   function(j) setnames(j,unlist(j[1,]))[-1]),fill = T)

return(datatable_format)
}

第一行代码只是创建了一个包含 2 个矩阵列表的列表列表。外部列表的元素数量等于字符串的初始向量的大小。内部列表正好有两个矩阵元素,其列数等于每个字符串元素中由“,”符号确定的字段数。每个列表列表中的第一个矩阵由列标题(由“=”符号确定)组成,第二个矩阵包含它们相等的值。最后一个 gsub 只是删除矩阵中剩余的任何特殊字符。如果您希望值中出现非字母数字字符,可能需要修改它。您的示例中没有任何内容。

第二行代码将这些列表转换为一个 data.table 对象。Reduce 函数只是简单地对 2 个元素列表进行 rbind,然后将它们转换为 data.tables。因此,对于每个初始字符串元素,现在只有一个包含 data.tables 的列表。“j” lapply 函数将列名设置为矩阵的第一行,然后从 data.table 中删除该行。最后的 rbindlist 调用组合了具有不同列数的 data.tables 列表。设置 fill=T 以允许组合它们,并且 NA 将分配给没有该特定字段的单元格。

我添加了第二个字符串元素和一个字段来测试代码:

 PubStr<-c("TY = \"txtTY1\",TI = \"txtTI1\"","TY = \"txtTY2\",TI = \"txtTI2\" ,TF = \"txtTF2\"")

 RIS_parser_fn(PubStr)

返回这个:

   TY     TI     TF
1: txtTY1 txtTI1   <NA>
2: txtTY2 txtTI2 txtTF2

希望这将帮助您和/或激发一些想法以获得更有效的代码。祝你好运!


推荐阅读