使用列名R中的id变量进行重新整形

时间:2015-03-16 12:59:08

标签: r reshape2

我已经和R一起工作了很长一段时间,但很少使用reshape或reshape2包。我目前正在尝试将数据集从宽格式转换为长格式,其中指标变量是变量名称的一部分。这是我的数据框的当前结构:

mydf <- data.frame(district = c(1:2),
v.mandate = c(1, 3),
s.mandate = c(2, 4),
v.perc = c(.4, .3),
s.perc = c(.5, .6))

> mydf
  district v.mandate s.mandate v.perc s.perc
1        1         1         2    0.4    0.5
2        2         3         4    0.3    0.6

我希望将其重新整理为长格式并提取&#34; v。&#34;和&#34; s。&#34;作为id变量(在实际数据集中,列表更长)。见下面的例子。

mydf2 <- data.frame(district = c(1, 1, 2, 2),
party = c("v", "s", "v", "s"),
mandate = c(1, 2, 3, 4),
perc = c(.4, .5, .3, .6))

> mydf2
  district party mandate perc
1        1     v       1  0.4
2        1     s       2  0.5
3        2     v       3  0.3
4        2     s       4  0.6

我尝试过使用reshape和melt函数,但我似乎无法从变量名中提取指标变量。而是将数据集重新整形为长格式,但将完整的变量名称作为id变量。见下面的例子。

> melt(mydf, id.vars=1)
  district  variable value
1        1 v.mandate   1.0
2        2 v.mandate   3.0
3        1 s.mandate   2.0
4        2 s.mandate   4.0
5        1    v.perc   0.4
6        2    v.perc   0.3
7        1    s.perc   0.5
8        2    s.perc   0.6

这可能是一个微不足道的问题,但我还没有能够在线找到解决方案。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

data.table v1.9.5可以直接融合到多个列。 Installation instructions

require(data.table) # v1.9.5+
ans = melt(setDT(mydf), measure=patterns("^mandate", "^perc"), 
             value.name=c("mandate", "perc"))
#    district variable mandate perc
# 1:        1        1       1  0.4
# 2:        2        1       3  0.3
# 3:        1        2       2  0.5
# 4:        2        2       4  0.6

setattr(ans$variable, 'levels', c("v", "s"))

您可以使用gsub()自动提取关卡。目前还没有直接提取关卡的方法(在所有情况下对我来说都不是直截了当的)。

答案 1 :(得分:2)

我可能不称职,但似乎你已经将变量命名为reshape所假设的变量(例如 v.mandate 而不是 mission.v )。我改变了他们的命名,并且可以让它起作用:

mydf <- data.frame(district = c(1:2),
                   mandate.v = c(1, 3),
                   mandate.s = c(2, 4),
                   perc.v = c(.4, .3),
                   perc.s = c(.5, .6))

#reshape data
mydf2 = reshape(mydf,
                varying=2:5, #variables 2:5 varies
                direction = "long", #towards long
                timevar="party", #the grouping variable
                idvar="district", #identifying variable
                sep = ".") #separated by dots

这给出了:

> mydf2
    district party mandate perc
1.v        1     v       1  0.4
2.v        2     v       3  0.3
1.s        1     s       2  0.5
2.s        2     s       4  0.6

您可能需要某种自动方式来反转整个数据框中的名称。我在上面手动完成,因为只有4个变量。如果你有100,那就不值得了。