聚集在前两排

gather on first two rows

我必须处理一些格式不正确的数据。它在前两行包含两个标识符,后面是数据。数据如下:

     V1       V2       V3
1  Date 12/16/18 12/17/18
2 Equip        a        b
3    x1        1        2
4    x2        3        4
5    x3        5        6

我想 gather 整理数据,但只有当您有单列名称时,收集才有效。我也试过研究传播。我想出的唯一解决方案非常老套,而且感觉不对。有没有一种优雅的方法来处理这个问题?

这是我想要的:

      Date Equip metric value
1 12/16/18     a     x1     1
2 12/16/18     a     x2     3
3 12/16/18     a     x3     5
4 12/17/18     b     x1     2
5 12/17/18     b     x2     4
6 12/17/18     b     x3     6

这种方法让我很接近,但我不知道如何处理糟糕的格式(没有 header,没有行名称)。如果格式正确,应该很容易gather

> as.data.frame(t(df))
         V1    V2 V3 V4 V5
V1     Date Equip x1 x2 x3
V2 12/16/18     a  1  3  5
V3 12/17/18     b  2  4  6

这是 dput

structure(list(V1 = c("Date", "Equip", "x1", "x2", "x3"), V2 = c("12/16/18", 
"a", "1", "3", "5"), V3 = c("12/17/18", "b", "2", "4", "6")), class = "data.frame", .Names = c("V1", 
"V2", "V3"), row.names = c(NA, -5L))

感谢您发布一个很好重现的问题。这是一些温和的 tidyr/dplyr 按摩。

library(tidyr)

df %>%
    gather(key = measure, value = value, -V1) %>%
    spread(key = V1, value = value) %>%
    dplyr::select(-measure) %>%
    gather(key = metric, value = value, x1:x3) %>%
    dplyr::arrange(Date, Equip, metric)
#>       Date Equip metric value
#> 1 12/16/18     a     x1     1
#> 2 12/16/18     a     x2     3
#> 3 12/16/18     a     x3     5
#> 4 12/17/18     b     x1     2
#> 5 12/17/18     b     x2     4
#> 6 12/17/18     b     x3     6

已针对 tidyr v1.0.0 更新:

这只是 pivot 函数的更简洁的语法。

df %>%
  pivot_longer(cols = -V1) %>%
  pivot_wider(names_from = V1) %>%
  pivot_longer(cols = matches("x\d"), names_to = "metric") %>%
  dplyr::select(-name)

这是从您使用 t() 的方法开始的另一种方法。我们可以替换第一行的 headers 然后删除第一行,只允许一个 gather 这可能更直观。

library(tidyverse)
df <- structure(list(V1 = c("Date", "Equip", "x1", "x2", "x3"), V2 = c(
  "12/16/18",
  "a", "1", "3", "5"
), V3 = c("12/17/18", "b", "2", "4", "6")), class = "data.frame", .Names = c(
  "V1",
  "V2", "V3"
), row.names = c(NA, -5L))

df %>%
  t() %>%
  `colnames<-`(.[1, ]) %>%
  `[`(-1, ) %>%
  as_tibble() %>%
  gather("metric", "value", x1:x3) %>%
  arrange(Date, Equip, metric)
#> # A tibble: 6 x 4
#>   Date     Equip metric value
#>   <chr>    <chr> <chr>  <chr>
#> 1 12/16/18 a     x1     1    
#> 2 12/16/18 a     x2     3    
#> 3 12/16/18 a     x3     5    
#> 4 12/17/18 b     x1     2    
#> 5 12/17/18 b     x2     4    
#> 6 12/17/18 b     x3     6

reprex package (v0.2.0) 创建于 2018-04-20。

您可以使用 reshape

library(reshape)
row.names(df) = df$V1
df$V1 = NULL
df = melt(data.frame(t(df)),id.var = c('Date','Equip'))
df[order(df$Date),]
      Date Equip variable value
1 12/16/18     a       x1     1
3 12/16/18     a       x2     3
5 12/16/18     a       x3     5
2 12/17/18     b       x1     2
4 12/17/18     b       x2     4
6 12/17/18     b       x3     6