【问题标题】:Reshaping Data with Multiple Sets of Column Variables使用多组列变量重塑数据
【发布时间】:2014-12-16 22:10:17
【问题描述】:

我正在尝试重塑我的一些数据,但 reshape2 包没有任何运气。鉴于我的数据,我所尝试的一切都不是我正在寻找的。​​p>

我有一个如下所示的 data.frame(其中 name1 对应于 age1,name2 对应于 age2,等等):

city <- c("New York", "Philadelphia", "Chicago")
state <- c("NY", "PA", "IL")
name1 <- c("Tim", NA, NA)
name2 <- c("Bob", "Jim", "Bill")
name3 <- c(NA, NA, "Jeff")
age1 <- c(40, NA, NA)
age2 <- c(30, 29, 34)
age3 <- c(NA, NA, 27)

df <- data.frame(city, state, name1, name2, name3, age1, age2, age3)

          city state name1 name2 name3 age1 age2 age3
1     New York    NY   Tim   Bob  <NA>   40   30   NA
2 Philadelphia    PA  <NA>   Jim  <NA>   NA   29   NA
3      Chicago    IL  <NA>  Bill  Jeff   NA   34   27

在我的实际数据集中,我有大约 50 个“姓名”和“年龄”变量。

最终,我的目标是 4 个变量:城市、州、姓名、年龄。我也不希望 NA 在我完成的数据集中。所以我想要实现的是:

          city state name age
1     New York    NY  Tim  40
2     New York    NY  Bob  30
3 Philadelphia    PA  Jim  29
4      Chicago    IL Bill  34
5      Chicago    IL Jeff  27

任何帮助将不胜感激!我已经尝试过 reshape2 和 tidyR 包,但还没有成功!

谢谢!

【问题讨论】:

    标签: r reshape


    【解决方案1】:

    “reshape2”中的melt 目前无法很好地处理这个问题,因为“name”和“age”列的类型不同。但是,更高版本的“data.table”(也将实现熔化)将允许您通过提供测量变量的list 来进行此类转换。 (见Issue #828,在“data.table”的V1.9.8中推出的功能。)

    与此同时,除了 base R 中的reshape,您还可以尝试我的“splitstackshape”包中的merged.stack

    library(splitstackshape)
    na.omit(merged.stack(df, var.stubs = c("name", "age"), sep = "var.stubs"))
    #            city state .id .t1 name age
    # 1:      Chicago    IL   2   2 Bill  34
    # 2:      Chicago    IL   3   3 Jeff  27
    # 3:     New York    NY   1   1  Tim  40
    # 4:     New York    NY   2   2  Bob  30
    # 5: Philadelphia    PA   2   2  Jim  29
    

    sep = "var.stubs" 表示变量存根和测量的“时间”之间没有分隔符。

    如果您还想删除不必要的列,可以将其复合到前面的语句中(或像 @MrFlick 那样使用 subset)。

    na.omit(
      merged.stack(df, var.stubs = c("name", "age"), 
                   sep = "var.stubs")[, c(
                     "city", "state", "name", "age"), with = FALSE])
    #            city state name age
    # 1:      Chicago    IL Bill  34
    # 2:      Chicago    IL Jeff  27
    # 3:     New York    NY  Tim  40
    # 4:     New York    NY  Bob  30
    # 5: Philadelphia    PA  Jim  29
    

    【讨论】:

    • Dang,我希望你能出现并从我对 MrFlick 帖子的评论中解决我的reshape 问题。唉,可怜的老reshape这次没把培根带回家。
    • @thelatemail,您的reshape 问题不是通过指定v.names 解决了吗?我同意它适用于一种方法但不适用于另一种方法似乎很奇怪。
    • 是的,但我确信我看到你在没有直接指定 v.names= 的情况下使 reshape 工作。我想我想象过那部分。
    • @thelatemail,也许你在想我的懒惰方法:reshape(df, direction = "long", varying = 3:ncol(df), sep = "")。如果我没记错的话,list 只有在列的顺序可能不同时才真正需要......
    • @thelatemail,这只猴子按对了键。我会得到奖励还是震惊?
    【解决方案2】:

    只需使用基本 R 函数,您就可以做到

    subset(reshape(df, list(paste0("name", 1:3), paste0("age", 1:3)), 
        v.names=c("name","age"),
        direction="long"), !is.na(name), select=-c(time, id))
    

    得到

                city state name age
    1.1     New York    NY  Tim  40
    1.2     New York    NY  Bob  30
    2.2 Philadelphia    PA  Jim  29
    3.2      Chicago    IL Bill  34
    3.3      Chicago    IL Jeff  27
    

    【讨论】:

    • 有趣的是,reshape(df[1:5],varying=3:5, direction="long", sep="") 正确地从 name1/2/3 猜测 name,但 reshape(df,varying=list(3:5,6:8), direction="long", sep="") 将其推高并分别从 name1/2/3age1/2/3 猜测 name1age1
    猜你喜欢
    • 2016-07-02
    • 2012-10-02
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 2015-10-08
    • 1970-01-01
    相关资源
    最近更新 更多