2016-01-21 21 views
1

在先前的问题,我不得不使用重塑一个问题:有没有办法在tbl中使用重塑?

reshape error - invalid 'row.names' length

小时后我意识到这是因为我用TBL格式,而不是data.frame。因此,使用重塑和保持TBL环境我要做的:

mydata %>% as.data.frame %>% reshape(, ...) %>% as.tbl 

,所以我想知道是否有另一种方式来做到这一点。

+0

'reshape'是非常缓慢和繁琐。你检查过'reshape2'包还是'tidyr'?他们都应该正常工作。 –

+1

这个问题必须让哈德利蠕动.... – A5C1D2H2I1M1N2O1R2T1

回答

1

更重要的是,有一个答案比任何其他原因,这里有四个选项要考虑。

首先,如果你想使用“dplyr”一起reshape,你就必须利用new.row.names争执中reshape,并将它们设置为你希望你的整形的数据集有行数的序列。计算很简单。取一列从宽格式到长格式的列的长度,并乘以原始数据集中的行数。

这种做法肯定会令Hadley不满,因此请自担风险。

mydf <- tbl_df(mydf) 
class(mydf) 
# [1] "tbl_df"  "tbl"  "data.frame" 

mydf %>% 
    reshape(
    idvar="g_id", 
    direction="long", 
    varying=list(c(5:14),c(15:24)), 
    v.names=c("PLC","P"), 
    new.row.names = seq_len(length(5:14) * nrow(mydf))) 

另一种方法,可能使哈德利不安,但有点少,是使用melt,但melt从“data.table”,而不是“reshape2”。当然,这会要求您将tbl_df转换为data.table,与您目前的方法非常相似,这需要采取另一个步骤。

library(data.table) 
mydf %>% 
    data.table %>% 
    melt(measure.vars = patterns("PLC[0-9]+", "P[0-9]+"), 
     value.name = c("PLC", "P")) 

的Hadleyverse之内,你可以试试 “tidyr”(由@DavidArenburg的建议)。这并不像他想象的那么美妙,因为它需要首先制作一个长数据集,然后再扩大它,不像上面的melt方法那样,只需一步就可以进行不太长的整形。

library(tidyr) 
mydf %>% 
    gather(var, val, starts_with("P")) %>% 
    mutate(var = gsub("([A-Z]+)", "\\1_", var)) %>% ## you can probably be clever and... 
    separate(var, into = c("variable", "time")) %>% ## come up with some fancier regex 
    spread(variable, val) 

最后,也是merged.stack从我的 “splitstackshape” 包。有了它,方法会是这样的:

library(splitstackshape) 
merged.stack(mydf, var.stubs = c("PLC", "P"), sep = "var.stubs")