在R中将数据框重塑为长格式。

4
我在R中遇到了reshape的问题。我计算了3个不同模型的2种类型的错误(err和rel_err),这给了我总共6个错误变量(即err_1、err_2、err_3、rel_err_1、rel_err_2和rel_err_3)。对于每种错误类型,我有3种不同类型的预测有效性测试(即随机保留集、回溯、预测)。我想把我的数据集变成长格式,以便我可以保持4种类型的测试,同时也使两种错误测量变得更长。因此,最终我将有一个名为err和一个名为rel_err的变量,以及一个id变量,用于指示错误对应的模型(1、2或3)。
目前我的数据如下:
iter       err_1  rel_err_1      err_2  rel_err_2      err_3  rel_err_3 test_type
1 -0.09385732 -0.2235443 -0.1216982 -0.2898543 -0.1058366 -0.2520759    random
1  0.16141630  0.8575728  0.1418732  0.7537442  0.1584816  0.8419816    back
1  0.16376930  0.8700738  0.1431505  0.7605302  0.1596502  0.8481901    front
1  0.14345986  0.6765194  0.1213689  0.5723444  0.1374676  0.6482615    random
1  0.15890059  0.7435382  0.1589823  0.7439204  0.1608709  0.7527580    back
1  0.14412360  0.6743928  0.1442039  0.6747684  0.1463520  0.6848202    front

以下是我希望它看起来的样子:

iter     model    err           rel_err    test_type
1        1        -0.09385732    (#'s)     random
1        2        -0.1216982     (#'s)     random
1        3        -0.1216982     (#'s)     random

并且...

我已经尝试了一些语法,但是无法弄清楚time.varying参数应该填什么。

非常感谢您提供的任何帮助。


2
我建议你首先查看reshape2包来处理这种情况。如果你真的想学习基本的reshape,可以查看我的两篇博客文章:(链接) - Tyler Rinker
我不久前问了一个非常类似的问题,并得到了一些相当不错的答案:链接 - eli-k
2个回答

5
你可以选择“困难”的方式来完成。为了透明度,你可以使用名称。
with( dat, data.frame(iter = rep(iter, 3), 
      model = rep(1:3, each = nrow(dat)),
      err = c(err_1, err_2, err_3), 
      rel_err = c(rel_err_1, rel_err_2, rel_err_3), 
      test_type = rep(test_type, 3)) )

或者,为了简洁起见,索引。

data.frame(iter = dat[,1], model = rep(1:3, each = nrow(dat)), err = dat[,c(2, 4, 6)], 
          rel_err = dat[,c(3, 5, 7)], test_type = dat[,8]) )

如果您有很多列,以传统方式可能需要使用grep命令来查找列名。
这种“传统”方法与reshape命令一样简洁,并且需要更少的思考如何使用命令。有时我会跳过考虑使用reshape命令的步骤。

这种方法看起来比reshape(包括reshape2工具)简单多了 - 有什么问题吗? - eli-k
1
如果您在宽数据中正确命名了列,那么重塑可能更加简洁。此外,该代码的复杂度与数据的复杂度成线性比例关系。这并不一定适用于reshape(2)语法。最后,如果您来回移动新的数据框,则该数据框具有属性,让reshape知道如何将其放回。因此,您可以只使用没有额外参数的reshape(longDat)来返回它。 - John

4
基本函数 reshape 可以让你做到这一点。
reshape(DT, direction = 'long', varying = list(paste('err',1:3,sep ='_'), paste('rel_err',1:3,sep ='_')), v.names = c('err','rel_err'), timevar = 'model')
    iter test_type model         err    rel_err id
1.1    1    random     1 -0.09385732 -0.2235443  1
2.1    1      back     1  0.16141630  0.8575728  2
3.1    1     front     1  0.16376930  0.8700738  3
4.1    1    random     1  0.14345986  0.6765194  4
5.1    1      back     1  0.15890059  0.7435382  5
6.1    1     front     1  0.14412360  0.6743928  6
1.2    1    random     2 -0.12169820 -0.2898543  1
2.2    1      back     2  0.14187320  0.7537442  2
3.2    1     front     2  0.14315050  0.7605302  3
4.2    1    random     2  0.12136890  0.5723444  4
5.2    1      back     2  0.15898230  0.7439204  5
6.2    1     front     2  0.14420390  0.6747684  6
1.3    1    random     3 -0.10583660 -0.2520759  1
2.3    1      back     3  0.15848160  0.8419816  2
3.3    1     front     3  0.15965020  0.8481901  3
4.3    1    random     3  0.13746760  0.6482615  4
5.3    1      back     3  0.16087090  0.7527580  5
6.3    1     front     3  0.14635200  0.6848202  6

我同意reshape的语法有时很难理解。我将详细说明此调用的工作方式:

  • direction = 'long' -- 重塑为long格式
  • varying = list(paste('err',1:3,sep ='_'), paste('rel_err',1:3,sep ='_')) -- 我们传递长度为2的列表,因为我们试图堆叠到两个不同的变量中。列paste('err',1:3,sep ='_')将成为长格式中的第一个新变量,paste('rel_err',1:3,sep ='_')) 将成为长格式中的第二个新变量。
  • v.names = c('err','rel_err') 设置长格式中两个新变量的名称
  • timevar = 'model' 设置时间标识符的名称(这里是宽格式中的_1)。

希望这样更清晰一些。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接