2016-01-21 65 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")