将两列数据转换为具有附加列类型的一列

Transform two columns data into one col with additional column type

我有以下数据框:

  Letter TimesInChapt1 TimesInChapt2
      A           100           111
      B           200           222
      C           300           333

我想把它改成下面这样:

  Letter        Times     ChapterNum
      A           100           1
      B           200           1
      C           300           1
      A           111           2
      B           222           2
      C           333           2

这是输出。

structure(list(Letter = structure(1:3, .Label = c("A", "B", "C"
), class = "factor"), TimesInChapt1 = c(100, 200, 300), 
TimesInChapt2 =     c(111, 
222, 333)), .Names = c("Letter", "TimesInChapt1", "TimesInChapt2"
), row.names = c(NA, -3L), class = "data.frame")

我可能可以使用 rbind 让它工作,但我想知道是否有我不知道的更好的解决方案。棘手的部分是保存数据来自哪一列。

我们可以使用dplyrtidyr。首先我们 gather 使数据变长而不是变宽,然后我们 extract_numeric 只得到章节的数字部分:

library(dplyr)
library(tidyr)
dat %>% gather(ChapterNum, Times, -Letter) %>%
        mutate(ChapterNum = extract_numeric((ChapterNum)))

  Letter ChapterNum Times
1      A          1   100
2      B          1   200
3      C          1   300
4      A          2   111
5      B          2   222
6      C          2   333

人们说 base R 中的 reshape 函数很难学习,对于某些应用程序来说,这可能是一个挑战。但是,如果您的数据已经很好地结构化,就像在这种情况下一样,那么使用它是一件轻而易举的事:

reshape(mydf, direction = "long", idvar = "Letter", varying = 2:3, sep = "")
#     Letter time TimesInChapt
# A.1      A    1          100
# B.1      B    1          200
# C.1      C    1          300
# A.2      A    2          111
# B.2      B    2          222
# C.2      C    2          333

您也可以尝试使用我的 "splitstackshape" 包中的 merged.stack,它可以像这样使用:

library(splitstackshape)
merged.stack(mydf, var.stubs = "TimesInChapt", sep = "var.stubs")