“字典”列表到data.table列

时间:2018-11-03 17:46:54

标签: r string data.table

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

我将在稍后解释有关RIS的更多信息,但仅限于以下内容:

我想使用类似以下内容的数据表:

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)rawToChar(resp$content)as.data.table()之后,我有一个数据表,其中每个发布都有行,一个具有上述字符串的名为PubStr的列。对于data.table的每一行,如何将此字符串转换为许多列。注意:某些行具有更多或更少的字段。

1 个答案:

答案 0 :(得分:0)

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

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函数简单地rbind 2个元素列表,然后将它们转换为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

希望这会帮助您和/或激发一些想法,以实现更高效的代码。祝你好运!