我对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.call
,daply
,strsplit
等的正确排列,但我没有到达任何地方。
什么是解决这个问题的简洁方法?
答案 0 :(得分:3)
如果DF
是输入数据框,则使用melt
将其从宽格式转换为长格式,删除NA行,将代码拆分为tag.name
和tag.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")
如果希望以时间戳顺序输出,请在最后一行中交换metric
和timestamp
。最后一行的结果是:
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>