【问题标题】:Splitting a variable name and melting the data with that split into separate columns in R拆分变量名称并将数据融合到 R 中的单独列中
【发布时间】:2015-09-15 04:51:06
【问题描述】:

我有一些我想要解析的 perfmon(Windows 性能日志数据)数据。

通常一组列名如下所示:

> colnames(p)
[1] "Time"                                                         
[2] "\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Queue Length"      
[3] "\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Read Queue Length" 
[4] "\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Write Queue Length"
[5] "\\\\testdb1\\Processor(_Total)\\% Processor Time"             
[6] "\\\\testdb1\\System\\Processes"                               
[7] "\\\\testdb1\\System\\Processor Queue Length"   

我将这些数据输入 R 的方式是:

p <- read.csv("r-perfmon.csv",stringsAsFactors = FALSE, check.names = FALSE)

这是一些示例数据

> head(p)
                     Time \\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Queue Length
1 04/15/2013 00:00:19.279                                             0.040037563
2 04/15/2013 00:00:34.279                                             0.009740260
3 04/15/2013 00:00:49.275                                             0.011009828
4 04/15/2013 00:01:04.284                                             0.006016244
5 04/15/2013 00:01:19.279                                             0.015125328
6 04/15/2013 00:01:34.275                                             0.002814141
  \\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Read Queue Length
1                                                  0.001421333
2                                                  0.000000000
3                                                  0.000206726
4                                                  0.000000000
5                                                  0.001894000
6                                                  0.000000000
  \\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Write Queue Length
1                                                   0.038616230
2                                                   0.009740260
3                                                   0.010803102
4                                                   0.006016244
5                                                   0.013231327
6                                                   0.002814141
  \\\\testdb1\\Processor(_Total)\\% Processor Time \\\\testdb1\\System\\Processes
1                                        29.569339                             86
2                                        10.856994                             86
3                                         7.733924                             81
4                                         1.910202                             81
5                                         6.164864                             81
6                                         1.351883                             81
  \\\\testdb1\\System\\Processor Queue Length
1                                           0
2                                           0
3                                           0
4                                           0
5                                           0
6                                           0

我希望能够解析列名然后融合数据。

所以如果我们以一列数据为例

> example <- p[2]
> head(example)
  \\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Queue Length
1                                             0.040037563
2                                             0.009740260
3                                             0.011009828
4                                             0.006016244
5                                             0.015125328
6                                             0.002814141

我希望它看起来像这样

Time, MachineName, Object, Counter, InstanceName, Value
04/15/2013 00:00:19.279, testdb1, PhysicalDisk, Avg. Disk Queue Length, 0 C:, 0.040037563
04/15/2013 00:00:34.279, testdb1, PhysicalDisk, Avg. Disk Queue Length, 0 C:, 0.009740260
04/15/2013 00:00:49.275, testdb1, PhysicalDisk, Avg. Disk Queue Length, 0 C:, 0.011009828

编辑:根据要求提供我的数据头部的 dput

structure(list(`(PDH-CSV 4.0) (GMT Daylight Time)(-60)` = c("04/15/2013 00:00:19.279", 
"04/15/2013 00:00:34.279", "04/15/2013 00:00:49.275", "04/15/2013 00:01:04.284", 
"04/15/2013 00:01:19.279", "04/15/2013 00:01:34.275"), `\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Queue Length` = c(0.040037563, 
0.00974026, 0.011009828, 0.006016244, 0.015125328, 0.002814141
), `\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Read Queue Length` = c(0.001421333, 
0, 0.000206726, 0, 0.001894, 0), `\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Write Queue Length` = c(0.03861623, 
0.00974026, 0.010803102, 0.006016244, 0.013231327, 0.002814141
), `\\\\testdb1\\Processor(_Total)\\% Processor Time` = c(29.56933862, 
10.85699395, 7.733924001, 1.910202013, 6.164864178, 1.351882837
), `\\\\testdb1\\System\\Processes` = c(86L, 86L, 81L, 81L, 81L, 
81L), `\\\\testdb1\\System\\Processor Queue Length` = c(0L, 0L, 0L, 
0L, 0L, 0L)), .Names = c("(PDH-CSV 4.0) (GMT Daylight Time)(-60)", 
"\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Queue Length", "\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Read Queue Length", 
"\\\\testdb1\\PhysicalDisk(0 C:)\\Avg. Disk Write Queue Length", 
"\\\\testdb1\\Processor(_Total)\\% Processor Time", "\\\\testdb1\\System\\Processes", 
"\\\\testdb1\\System\\Processor Queue Length"), row.names = c(NA, 
6L), class = "data.frame")

【问题讨论】:

  • 首先在 r 中使用reshape 将数据重新整形为长格式,然后在最后的列名上使用strsplit。如果您希望其他人复制您的数据,您还需要dput您的数据。
  • 我有长格式 p &lt;- melt(p, id=c("time")) 但我正在努力解决 strsplit
  • 在宽格式中,您可以一次更改每一列...但我不确定最终数据集的外观。但是对于您的示例..s &lt;- strsplit(colnames(example), "\\\\|\\)|\\(")[[1]] ; data.frame(t(s[nzchar(s)]), example[[1]])
  • 根据要求,我已经包含了我的数据头部的 dput
  • Gauss...感谢您的编辑,但您能否将问题中的dput 复制到新的 R 会话中?由于单个反斜杠,它给我抛出了一个错误

标签: r string data-cleaning


【解决方案1】:

要知道最终数据应该是什么样子有点困难,就好像每个列名都被反斜杠或方括号分开一样,根据输入列,结果中的列数会有所不同。

所以我将每一列拆分为一个单独的列表元素。如果您的dput 中的data.frame 被称为d

# Look at second column - then all you need to do is tweak the names
s <- strsplit(colnames(d)[2], "\\\\|\\)|\\(")[[1]]
data.frame(time = d[[1]], t(s[nzchar(s)]), value=d[[2]])

                     time      X1           X2   X3                     X4       value
1 04/15/2013 00:00:19.279 testdb1 PhysicalDisk 0 C: Avg. Disk Queue Length 0.040037563
2 04/15/2013 00:00:34.279 testdb1 PhysicalDisk 0 C: Avg. Disk Queue Length 0.009740260
3 04/15/2013 00:00:49.275 testdb1 PhysicalDisk 0 C: Avg. Disk Queue Length 0.011009828
4 04/15/2013 00:01:04.284 testdb1 PhysicalDisk 0 C: Avg. Disk Queue Length 0.006016244
5 04/15/2013 00:01:19.279 testdb1 PhysicalDisk 0 C: Avg. Disk Queue Length 0.015125328
6 04/15/2013 00:01:34.275 testdb1 PhysicalDisk 0 C: Avg. Disk Queue Length 0.002814141

strsplit 在\\ 或( 或) 处拆分每个字符串 - 请注意在R 中这些需要用前导\\ 转义。这会导致一些空字符串被 nzchar 函数删除(如果长度为零则返回 FALSE)

# Apply it over all variables
lapply(seq_along(colnames(d))[-1], function(i) {
                 s <- strsplit(colnames(d)[[i]], "\\\\|\\)|\\(")[[1]]
                 data.frame(time = d[[1]], t(s[nzchar(s)]), value=d[[i]])
})

同样,您需要重命名列。

【讨论】:

  • 感谢您,这是一个很好的起点。这段代码似乎发生了什么,我最终得到了一个包含很多列时间的数据框,x1,x2,time.1,x1.1,x2.1,time.2,x1.2 等。我希望数据将只有时间,x1,x2 列。这有意义吗?
  • 嗨 Gauss,我不太确定预期的输出应该是什么样子,当我刚刚在第二列中完成时,它与您的问题的预期结果相匹配。由于列名分为不同数量的部分,我不确定如何/是否要组合它们。你能指出你想如何组合多列的输出吗?
  • 也许创建三个数据框。 PhysicalDisk、Processor 和 System 各一个,并将公共列 rbind 在一起?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
  • 2022-10-13
相关资源
最近更新 更多