Reorganize/reshape 数据框

Reorganize/reshape data frame

我有一个活套的数据框。有两个系统,每个系统具有不同的状态。给出了每个状态的周数和人数。

df <- data.frame (sys = rep(c("a","b"), each=3), 
              sta = rep(c("L","T","P"), times=2), 
              w01 = c("0","2","5","2","2","5"),
              w02 = c("3","2","2","4","6","1"),
              w03 = c("4","1","0","5","3","0"))
df
sys  sta  w01  w02  w03
a    L    0    3    4
a    T    2    2    1
a    P    5    2    0
b    L    2    4    5
b    T    2    6    3
b    P    5    1    0

我想要一个数据框,显示每个号码的系统和状态。结果将如下所示:

sys sta Num
a   L   0
a   L   3
a   L   4
a   T   2
a   T   2
a   T   1
a   P   5
a   P   2
a   P   0
b   L   2
b   L   4
b   L   5
b   T   2
b   T   6
b   T   3
b   P   5
b   P   1
b   P   0

我完全不知道该怎么做。我找到了这两个 questions/answers Reshaping data.frame from wide to long format 但找不到适合我的问题的方法。 我也试过 reshapedirection = "wide" 没有给出我需要的输出,我被 direction = "long" 的不同部分所吸引。这是我尝试过的方法,但没有用...

a <- as.vector(colnames(df[-c(1,2)]))
df2 <- reshape(df, idvar = "sys", timevar = "sta", varying = a , direction = "long")

有什么解决这个问题的建议吗? 谢谢大家和亲切的问候!

P.S.: 我需要我的数据集的 "new format" 来进行 friedman 测试 (friedman.test)。会这样吗?

tidyrdplyr:

library(tidyr)
library(dplyr)

df %>% 
    gather(key, value, -sys, -sta) %>% 
    select(-key) %>% 
    arrange(sys, sta)

#>    sys sta value
#> 1    a   L     0
#> 2    a   L     3
#> 3    a   L     4
#> 4    a   P     5
#> 5    a   P     2
#> 6    a   P     0
#> 7    a   T     2
#> 8    a   T     2
#> 9    a   T     1
#> 10   b   L     2
#> 11   b   L     4
#> 12   b   L     5
#> 13   b   P     5
#> 14   b   P     1
#> 15   b   P     0
#> 16   b   T     2
#> 17   b   T     6
#> 18   b   T     3

您可以使用 reshape2

中的 melt
melt(df, id.vars = c("sys","sta"), value.name = "num")

#     sys sta variable num
# 1    a   L      w01   0
# 2    a   T      w01   2
# 3    a   P      w01   5
# 4    b   L      w01   2
# 5    b   T      w01   2
# 6    b   P      w01   5
# 7    a   L      w02   3
# 8    a   T      w02   2
# 9    a   P      w02   2
# 10   b   L      w02   4
# 11   b   T      w02   6
# 12   b   P      w02   1
# 13   a   L      w03   4
# 14   a   T      w03   1
# 15   a   P      w03   0
# 16   b   L      w03   5
# 17   b   T      w03   3
# 18   b   P      w03   0

如果要删除 variable 列,请使用

melt(df, id.vars = c("sys","sta"), value.name = "num")[,c(1,2,4)]

这是一个tidyverse方法:

它是 tidyr 包的一部分,包含在 tidyverse

library(tidyverse)
out <- gather(df, key = 'week', value = 'number', -sys, -sta)

输出:

   sys sta week number
1    a   L  w01      0
2    a   T  w01      2
3    a   P  w01      5
4    b   L  w01      2
5    b   T  w01      2
6    b   P  w01      5
7    a   L  w02      3
8    a   T  w02      2
9    a   P  w02      2
10   b   L  w02      4
11   b   T  w02      6
12   b   P  w02      1
13   a   L  w03      4
14   a   T  w03      1
15   a   P  w03      0
16   b   L  w03      5
17   b   T  w03      3
18   b   P  w03      0

工作原理:

  • gather 获取所有未排除的列。通过将 select 语句传递给 ... 参数来处理排除。在这种情况下,我排除了 syssta。因此,我们 gather 从中获取值的唯一列是 all_w.
  • 此外,我们为 keyvalue 字段指定了一个名称。键字段将包含从中获取输出的每个元素(行)的列名。 value 将在该列中包含该行的内容。
  • 我建议保留 week,因为您稍后可能想知道生成其中一个数字的曝光时间。如果没有,您可以使用 df %>% select(-week).
  • 删除它
  • 您可以通过 spread(out, key = week, value = number) 撤消此转换。瞧,你的老 df!