【问题标题】:R: convert data from wide to long - multiple conditions - getting error [duplicate]R:将数据从宽转换为长-多个条件-出现错误[重复]
【发布时间】:2016-07-19 01:56:38
【问题描述】:

我有如下数据,我想将其转换为长格式。

id count a1     b1 c1   a2     b2 c2  a3    b3  c3  age
1  1     apple  2  3    orange 3  2   beer   2   1   50
1  2     orange 3  2    apple  2  2   beer   2   1   50
2  1     pear   3  2    apple  2  2   orange 2   2   45

[a1,b1,c1],[a2,b2,c2],[a3,b3,c3] 是具有指定 id 的人所面临的三个属性的集合,此人可能面临多项选择情况表示第 i 个选择情况。我想将其改回长格式,同时保留其他变量,如下所示:

id count    a    b  c  age
1  1      apple  2  3  50
1  1      orange 3  2  50
1  1      beer   2  1  50
1  2      orange 3  2  50
1  2      apple  2  2  50
1  2      beer   2  1  50
2  1      pear   3  2  45
2  1      apple  2  2  45
2  1      orange 2  2  45

我曾尝试使用以下命令进行 reshape,但对于在何处处理 timevar 和 times 感到困惑:

 l <- reshape(df, 
           varying = df[,3:11],
           v.names = c("a","b","c"),
           timevar = "choice", 
           times = c("a","b","c"), 
           direction = "long")

使用上述命令,我无法得到我想要的结果,非常感谢任何帮助!

【问题讨论】:

    标签: r data-manipulation


    【解决方案1】:

    使用data.table 包中的melt 函数:

    library(data.table)
    setDT(df)
    melt(df, id.vars = c('id', 'count', 'age'),  
             measure = patterns('a\\d', 'b\\d', 'c\\d'), 
             # this needs to be regular expression to group `a1, a2, a3` etc together and 
             # the `\\d` is necessary because you have an age variable in the column.
             value.name = c('a', 'b', 'c'))[, variable := NULL][order(id, count, -age)]
    
    #    id count age      a b c
    # 1:  1     1  50  apple 2 3
    # 2:  1     1  50 orange 3 2
    # 3:  1     1  50   beer 2 1
    # 4:  1     2  50 orange 3 2
    # 5:  1     2  50  apple 2 2
    # 6:  1     2  50   beer 2 1
    # 7:  2     1  45   pear 3 2
    # 8:  2     1  45  apple 2 2
    # 9:  2     1  45 orange 2 2
    

    【讨论】:

      【解决方案2】:

      要使用reshape 函数,您只需调整变量参数即可。它可以是一个列表,您希望将构成同一列的变量作为向量放在一个列表中:

      reshape(df, 
              idvar=c("id", "count", "age"),
              varying = list(c(3,6,9), c(4,7,10), c(5,8,11)),
              timevar="time",
              v.names=c("a", "b", "c"), 
              direction = "long")
      

      返回

               id count age time      a b c
      1.1.50.1  1     1  50    1  apple 2 3
      1.2.50.1  1     2  50    1 orange 3 2
      2.1.45.1  2     1  45    1   pear 3 2
      1.1.50.2  1     1  50    2 orange 3 2
      1.2.50.2  1     2  50    2  apple 2 2
      2.1.45.2  2     1  45    2  apple 2 2
      1.1.50.3  1     1  50    3   beer 2 1
      1.2.50.3  1     2  50    3   beer 2 1
      2.1.45.3  2     1  45    3 orange 2 2
      

      我还添加了 idvar,因为我认为这通常是对其他人或重新阅读旧代码的好习惯。

      数据

      df <- read.table(header=T, text="id count a1     b1 c1   a2     b2 c2  a3    b3  c3  age
      1  1     apple  2  3    orange 3  2   beer   2   1   50
      1  2     orange 3  2    apple  2  2   beer   2   1   50
      2  1     pear   3  2    apple  2  2   orange 2   2   45")
      

      【讨论】:

      • 当我尝试时,它显示 Error in .subset(x, j) : invalid subscript type 'list'
      • 我刚刚开始了一个新的 R 会话,并使用我刚刚添加的数据运行了代码,没有出现错误。
      • 您不需要手动指定不同的组或名称,reshape() 可以猜到 reshape(dat, idvar=c("id","count","age"), direction="long", varying=3:11, sep="") sep="" 只是声明每个 a/b/c1/2/3 由没有"",允许推断timevarv.names
      • 但是我有时,如果我使用了varying = xx:xx,我会得到一个错误,说无法从名字中猜测时变变量。你能告诉我这个错误是什么意思吗?
      • @lll - 如果变量不是grp.1 grp.2 othergrp.1 othergrp.2 等形式,则必须指定sep=,因为sep=. 是默认值。
      【解决方案3】:

      我们可以使用dplyr/tidyr

      library(dplyr)
      library(tidyr)
      gather(df1, Var, Val, a1:c3) %>%
             extract(Var, into = c("Var1", "Var2"), "(.)(.)") %>%
             spread(Var1, Val) %>%
             select(-Var2)
      #   id count age      a b c
      #1  1     1  50  apple 2 3
      #2  1     1  50 orange 3 2
      #3  1     1  50   beer 2 1
      #4  1     2  50 orange 3 2
      #5  1     2  50  apple 2 2
      #6  1     2  50   beer 2 1
      #7  2     1  45   pear 3 2
      #8  2     1  45  apple 2 2
      #9  2     1  45 orange 2 2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-29
        • 1970-01-01
        • 2020-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多