从R中的TSV中解析键值对

时间:2013-05-06 21:52:35

标签: r

我对R来说比较新,所以我不像有经验的用户那样在矢量空间中这么清楚。我有一个格式如下的数据框:

              metric timestamp               value           tag1     tag2   tag3 tag4 tag5 tag6 tag7 tag8 tag9 tag10
1 dummy.random.unif 1367848802  0.9936670064926147 host=localhost blah=foo   NA   NA   NA   NA   NA   NA   NA    NA
2 dummy.random.unif 1367848822 0.19621700048446655 host=localhost blah=bar   NA   NA   NA   NA   NA   NA   NA    NA
3 dummy.linear      1367848842                97.6 shmoo=whatever NA         NA   NA   NA   NA   NA   NA   NA    NA
4 dummy.random.unif 1367848862  0.3171229958534241 host=localhost blah=foo   NA   NA   NA   NA   NA   NA   NA    NA
5 dummy.linear      1367848882                97.7 shmoo=whatever NA         NA   NA   NA   NA   NA   NA   NA    NA
6 dummy.random.unif 1367848902  0.2197140008211136 host=localhost blah=foo   NA   NA   NA   NA   NA   NA   NA    NA

如您所见,列tag1:tag10包含键值对。但并不总是相同的键,并不总是相同数量的键。我想将这个数据框转换为更像这样的东西,这样更方便消费:

              metric timestamp               value   tag.host tag.blah tag.shmoo 
1 dummy.random.unif 1367848802  0.9936670064926147  localhost      foo        NA
2 dummy.random.unif 1367848822 0.19621700048446655  localhost      bar        NA
3 dummy.linear      1367848842                97.6         NA       NA  whatever
4 dummy.random.unif 1367848862  0.3171229958534241  localhost      foo        NA
5 dummy.linear      1367848882                97.7         NA       NA  whatever
6 dummy.random.unif 1367848902  0.2197140008211136  localhost      foo  whatever

现在我知道我可以在程序上做到这一点,但它会很笨重,而且我听说使用R的正确方法是考虑对整个向量的操作(而不是循环遍历它们)。我花了几个小时试图找出do.calldaplystrsplit等的正确排列,但我没有到达任何地方。

什么是解决这个问题的简洁方法?

1 个答案:

答案 0 :(得分:3)

如果DF是输入数据框,则使用melt将其从宽格式转换为长格式,删除NA行,将代码拆分为tag.nametag.value并重新塑造如图所示,它回到了广泛的位置:

library(reshape2)
m <- na.omit(melt(DF, id = 1:3, value.name = "tag"))
m.tr <- transform(m, tag.name = sub("=.*", "", tag), 
                     tag.value = sub(".*=", "", tag))
dcast(metric + timestamp + metric + value ~ tag.name, data=m.tr, 
      value.var="tag.value")

如果希望以时间戳顺序输出,请在最后一行中交换metrictimestamp。最后一行的结果是:

             metric  timestamp     value blah      host    shmoo
1      dummy.linear 1367848842 97.600000 <NA>      <NA> whatever
2      dummy.linear 1367848882 97.700000 <NA>      <NA> whatever
3 dummy.random.unif 1367848802  0.993667  foo localhost     <NA>
4 dummy.random.unif 1367848822  0.196217  bar localhost     <NA>
5 dummy.random.unif 1367848862  0.317123  foo localhost     <NA>
6 dummy.random.unif 1367848902  0.219714  foo localhost     <NA>