首页 > 解决方案 > R重构数据框

问题描述

data1=data.frame("grade"=c(rep(1:3,6)),
                "class" = c(rep(c(rep('a',3),rep('b',3)),3)),
"score"=c(rep(c('p','p','p','s','s','s','q','q','q'),2)),
"p"=c(-9:8),
"s"=c(1:18),
"q"=c(21:38))


data2=data.frame("grade"=c(rep(1:3,6)),
                  "class" = c(rep(rep('a',3),rep('b',3),3)),
                "pp"=c(-9,-8,-7,0,1,2),
                "ps"=c(1,2,3,10,11,12),
                "pq"=c(21,22,23,30,31,32),
                "sp"=c(-6,-5,-4,3,4,5),
                "ss"=c(4,5,6,13,14,15),
                "sq"=c(24,25,26,33,34,35),
                "qp"=c(-3,-2,-1,6,7,8),
                "qs"=c(7,8,9,16,17,18),
                "qq"=c(27,28,29,36,37,38))

我拥有的是data1,我想做data2。我的英语不太好,所以我制作了这两个示例数据框来展示我想要的。基本上将'data1'中的'score'与data1中的列名'p'和'q'和'q'结合起来创建'data2'。

我有大量的学区数据,所以如果可能的话,希望有一个快速的 data.table 解决方案。也有兴趣查看 dplyr 或其他简单的解决方案!

然后我想知道如何按等级和“班级”对“data2”[pp-qq]的所有列进行ggplot

dcast(setDT(data1), Grade + class + rowid(score) ~ score, value.var = c('p', 's', 'q'), sep="")[, score := NULL][ ]

在此处输入图像描述

两步希望输出,终极愿望是一个在底部,一个在顶部是中间-

在此处输入图像描述

____________________________________________________________________________ 一位成员在重铸数据框时给了我一个非常好的答案:

data1=data.frame("grade"=c(rep(1:3,6)),
                 "class" = c(rep(c(rep('a',3),rep('b',3)),3)),
                 "score"=c(rep(c('p','p','p','s','s','s','q','q','q'),2)),
                 "p"=c(-9:8),
                 "s"=c(1:18),
                 "q"=c(21:38))


d2=dcast(melt(setDT(data1), id.var = 1:3)[, c('score', 'variable') := 
                                         lapply(.SD, function(x) setNames(c(3, 5, 9), c('p', 's', 'q'))[x]),
                                       .SDcols = c('score', 'variable')],grade + class ~ 
        paste0('x', score, variable), value.var = 'value')

它工作完美。然而,在我的应用程序中,我有更多的变量。当我什至只添加 1 时,我打破了它:

data1=data.frame("col1"=c(1),
  "grade"=c(rep(1:3,6)),
                 "class" = c(rep(c(rep('a',3),rep('b',3)),3)),
                 "score"=c(rep(c('p','p','p','s','s','s','q','q','q'),2)),
                 "p"=c(-9:8),
                 "s"=c(1:18),
                 "q"=c(21:38))


d2=dcast(melt(setDT(data1), id.var = 1:3)[, c('score', 'variable') := 
                                         lapply(.SD, function(x) setNames(c(3, 5, 9), c('p', 's', 'q'))[x]),
                                       .SDcols = c('score', 'variable')], col1 + grade + class ~ 
        paste0('x', score, variable), value.var = 'value')

[.data.table(melt(setDT(data1), id.var = 1:3), , :=(c("score", : .SDcols 的某些项目不是列名:[score] :警告消息:在 melt.data.table(setDT(data1), id.var = 1:3) 中:'measure.vars' [score, p, s, q] 并非都是同一类型。按顺序层次结构,熔融数据值列将是“字符”类型。所有非“字符”类型的度量变量也将被强制。检查 ?melt.data.table 中的详细信息以获取有关强制的更多信息。

也许有一种方法可以减少破坏的可能性?非常感谢您的帮助!

标签: rdplyrdata.table

解决方案


您可以reshape为此使用基本功能。

我需要添加一个额外的变量 ( unique) 来区分data1. 如果您不需要它,您可以在之后删除它。

data1$unique <- rep(1:2, each=9)

reshape(data=data1, 
        direction="wide",
        v.names=c("p","s","q"),
        timevar="score",
        idvar=c("grade","class","unique"),
        sep="")

   grade class unique pp sp qp ps ss qs pq sq qq
1      1     a      1 -9  1 21 -6  4 24 -3  7 27
2      2     a      1 -8  2 22 -5  5 25 -2  8 28
3      3     a      1 -7  3 23 -4  6 26 -1  9 29
10     1     a      2  0 10 30  3 13 33  6 16 36
11     2     a      2  1 11 31  4 14 34  7 17 37
12     3     a      2  2 12 32  5 15 35  8 18 38


推荐阅读