【问题标题】:Reshape wide data to long with multiple rows using data.table使用 data.table 将宽数据重塑为多行数据
【发布时间】:2018-08-05 09:12:48
【问题描述】:

我有如下数据

#    am     qsec        vs am     gear     carb
# 1:  1 17.36000 0.5384615  1 4.384615 2.923077
# 2:  1 17.02000 1.0000000  1 4.000000 2.000000
# 3:  0 18.18316 0.3684211  0 3.210526 2.736842
# 4:  0 17.82000 0.0000000  0 3.000000 3.000000

我想制作

 #    variable          0          1
 # 1:     qsec 18.1831579 17.3600000
 # 2:     qsec 17.8200000 17.0200000
 # 3:       vs  0.3684211  0.5384615
 # 4:       vs  0.0000000  1.0000000
 # 5:       am  0.0000000  1.0000000
 # <snip>

输入数据中的am 组用作输出数据中的列。

我可以通过多个步骤来做到这一点(如下面的“数据输出”所示),但我希望能够以更data.tabley 的方式做到这一点。我怎样才能 请使用data.table 重塑此数据以产生预期结果。

我的复制尝试和数据

library(data.table)
data = setDT(mtcars[7:11])

# data in
tdat = data[, lapply(.SD, function(y){
                      unlist(lapply(c(mean, median), function(f) f(y) ))
                   }),
                  by="am", .SDcols=seq_along(data)
              ]


# data out  
m = melt(tdat, id.vars="am")
m[, r:=duplicated(interaction(am, variable))+0L]      
dcast(m, variable + r ~ am, value.var = "value")[, r:=NULL][]

我问了similar question,但使用 cmets 中给出的 Akrun 解决方案返回

dcast( melt(tdat, id.var=1), variable~am, value.var='value')
#Aggregate function missing, defaulting to 'length'
#   variable 0 1
#1:     qsec 2 2
#2:       vs 2 2
#3:       am 2 2
#4:     gear 2 2
#5:     carb 2 2

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    这可以使用data.tablerowid()函数解决:

    library(data.table)
    m <- melt(tdat, id.vars="am")
    dcast(m, variable + rowid(am) ~ am)[, am := NULL][]
    
        variable          0          1
     1:     qsec 18.1831600 17.3600000
     2:     qsec 17.8200000 17.0200000
     3:       vs  0.3684211  0.5384615
     4:       vs  0.0000000  1.0000000
     5:       am  0.0000000  1.0000000
     6:       am  0.0000000  1.0000000
     7:     gear  3.2105260  4.3846150
     8:     gear  3.0000000  4.0000000
     9:     carb  2.7368420  2.9230770
    10:     carb  3.0000000  2.0000000
    

    数据

    library(data.table)
    tdat <- fread(
    "# i    am     qsec        vs am     gear     carb
    # 1:  1 17.36000 0.5384615  1 4.384615 2.923077
    # 2:  1 17.02000 1.0000000  1 4.000000 2.000000
    # 3:  0 18.18316 0.3684211  0 3.210526 2.736842
    # 4:  0 17.82000 0.0000000  0 3.000000 3.000000", 
      drop = 1:2, colClasses = list(integer = c(3, 6))
    )
    

    或者,可以以更简洁的方式生成示例数据集而不用加倍am 列:

    setDT(mtcars[7:11])[, lapply(.SD, function(y) c(mean(y), median(y))), by = am]
    
       am     qsec        vs     gear     carb
    1:  1 17.36000 0.5384615 4.384615 2.923077
    2:  1 17.02000 1.0000000 4.000000 2.000000
    3:  0 18.18316 0.3684211 3.210526 2.736842
    4:  0 17.82000 0.0000000 3.000000 3.000000
    

    【讨论】:

      猜你喜欢
      • 2013-08-24
      • 2017-11-04
      • 1970-01-01
      • 2016-05-25
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      • 2017-07-19
      相关资源
      最近更新 更多