【问题标题】:reshape wide into long while splitting分裂时将宽改造成长
【发布时间】:2014-07-11 02:40:33
【问题描述】:

我正在寻找重塑:

  ID p2012 p2010 p2008 p2006 c2012 c2010 c2008 c2006
1  1   160   162   163   165  37.3  37.3  37.1  37.1
2  2   163   164   164   163   2.6   2.6   2.6   2.6

进入:

    ID  year    p   c
1   1   2006    165 37.1
2   1   2008    164 37.1
3   1   2010    162 37.3
4   1   2012    160 37.3
5   2   2006    163 2.6
6   2   2008    163 2.6
7   2   2010    164 2.6
8   2   2012    163 2.6

我是 R 新手,一直在尝试使用 meltdcast 函数,但在这个阶段对我来说有很多曲折。非常感谢您的帮助!

我的 df 的 dput

structure(list(ID = 1:2, p2012 = c(160L, 163L), p2010 = c(162L, 164L), p2008 = 163:164, p2006 = c(165L, 163L), c2012 = c(37.3, 2.6), c2010 = c(37.3, 2.6), c2008 = c(37.1, 2.6), c2006 = c(37.1, 2.6)), .Names = c("ID", "p2012", "p2010", "p2008", "p2006", "c2012", "c2010", "c2008", "c2006"), class = "data.frame", row.names = c(NA, -2L))

【问题讨论】:

  • 欢迎来到 SO!也许您可以让我们更简单地回答您的问题:使用dput(yourDF) R 为您提供代码,您可以在此处转储,这使我们能够在安装过程中在几秒钟内重建您的数据。

标签: r reshape2 tidyr melt


【解决方案1】:

您可能必须先melt 数据,然后拆分变量和年份,然后将dcast 拆分为最终的data.frame

require(reshape2)
# melt data.frame
dfmelt <- melt(df, id.vars="ID", variable.name="var.year")
# split "var.year" into new variables "var" and "year" 
dfmelt[, "var"] <- gsub("[0-9]", "", as.character(dfmelt[, "var.year"]))
dfmelt[, "year"] <- as.numeric(gsub("[a-z, A-Z]", "", as.character(dfmelt[, "var.year"])))
# cast to data with column for each var-name
dcast(dfmelt, ID+year~var, value.var="value")

【讨论】:

    【解决方案2】:

    shadow 的替代方法是使用reshape 函数:

    reshape(d, direction='long', varying=list(2:5, 6:9), v.names=c("p", "c"), idvar="ID", times=c(2012, 2010, 2008, 2006))
    

    这假设您事先知道 pc 的列索引(或添加额外的代码来计算它们)。此外,上面的时间向量可以通过使用类似于阴影的gsub 函数来找到。

    使用哪种方式可能是个人喜好问题。

    【讨论】:

    • 谢谢,你们太棒了!两种方式都适合我。
    • 如果您不知道正确的索引,list(grep('p',colnames(d)),grep('c',colnames(d)))
    • 感谢您的规范,我可以reshape我原来的data.frame!
    【解决方案3】:

    也可以使用来自tidyr 的以下解决方案。您实际上不需要使用正则表达式,如果“p”或“c”始终是列名的第一个字母:

    library(tidyr)
    library(dplyr) # only loaded for the %>% operator
    
    dat %>%
      gather(key,value,p2012:c2006) %>%
      separate(key,c("category","year"),1) %>%
      spread(category,value)
      ID year    c   p
    1  1 2006 37.1 165
    2  1 2008 37.1 163
    3  1 2010 37.3 162
    4  1 2012 37.3 160
    5  2 2006  2.6 163
    6  2 2008  2.6 164
    7  2 2010  2.6 164
    8  2 2012  2.6 163
    

    【讨论】:

    • 是的,这也有效。谢谢。 tidyr & dplyr 很好,只是用于其他数据。
    猜你喜欢
    • 2021-08-01
    • 2014-07-19
    相关资源
    最近更新 更多