2016-01-13 34 views
4

我有一個包含的識別信息的兩個列上並通過連字符分隔的字母對中的一列的數據幀新的列名:拆分列到相鄰的列,使用行的名稱中的R

df<-data.frame(
    list = rep(1:3, each = 2), 
    set = rep(c("A","B"), times = 3), 
    item = c("ab-cd","ef-gh","ij-kl","mn-op","qr-st","uv-wx") 
    ) 

我一直在努力實現的是將數據框轉換爲以下形式,其中:1.由「列表」索引的單獨行被摺疊成一行; 2.「項目」欄以連字符作爲分隔符分割成相鄰列; 3.「設置」列作爲命名結果列的基礎。

df2 <- data.frame(
     list = c(1:3), 
     A_1 = c("ab", "ij", "qr"), 
     A_2 = c("cd", "kl", "st"), 
     B_1 = c("ef", "mn", "uv"), 
     B_2 = c("gh", "op", "wx")) 

我與reshape提到了許多以前張貼的問題(特別是在[此處]),並試圖使用BASE轉置函數與各種結合功能沿着接近溶液一步工序中,沿着包和splitstackshape包。我的近解決方案都不是很好,我想知道是否有一個好的方法來做到這一點。

一如既往,我非常感謝社區的意見和反饋。

+0

你能展示一些你的解決方案嗎?你可能快到了! – Heroka

+0

查看'tidyr'軟件包,例如https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf –

+0

你需要dplyr/tidy包來完成圖片 - group_by()在dplyr和spread()在tidyr應該有幫助。 – Gopala

回答

5

非常感謝@AnandaMahto:它可以通過首先重塑,然後分裂而不是其他方式完成。

library(splitstackshape) 
cSplit(dcast(as.data.table(df), list ~ set, value.var = "item"), c("A", "B"), "-") 

我們可以使用base R和reshape2在兩個步驟中完成。

首先,我們創建包含分割項目的列'1'和'2'。通常情況下,我們不會使用數字字符來啓動列名,但它爲我們節省了後續重命名結果列的一個步驟。

df[,c("1","2")] <- do.call(rbind,strsplit(as.character(df$item),"-")) 

然後我們使用recast

res <- recast(data=df, list~set+variable, measure.var=c("1","2")) 
res 

    list A_1 A_2 B_1 B_2 
1 1 ab cd ef gh 
2 2 ij kl mn op 
3 3 qr st uv wx 
+0

抱歉,我無法及時發佈失敗解決方案的示例,但這是一個有用的答覆。非常感謝@Heroka –

+1

我會做'cSplit(dcast(as.data.table(df),list_set,value.var =「item」),c(「A」,「B」),「 - 「)'.... – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto非常感謝!我已經將它添加到答案中,希望對你有用(並刪除了我的兩步拆分式解決方案)。 – Heroka

1

爲了完整起見,這也很好地工作在Hadleyverse內:

library(dplyr) 
library(tidyr) 
df %>% 
    separate(item, 1:2) %>% 
    gather(val, item, -set, -list) %>% 
    mutate(set=paste(set, val, sep="_")) %>% 
    select(-val) %>% 
    spread(set, item) 
# list A_1 A_2 B_1 B_2 
# 1 1 ab cd ef gh 
# 2 2 ij kl mn op 
# 3 3 qr st uv wx 
1

爲了完整起見,這也很好地工作與Hadleyverse的基地R剋星,reshape

reshape(cbind(df[-3], 
       do.call(rbind, strsplit(as.character(df$item), "-"))), 
     direction = "wide", idvar = "list", timevar = "set") 
# list 1.A 2.A 1.B 2.B 
# 1 1 ab cd ef gh 
# 3 2 ij kl mn op 
# 5 3 qr st uv wx 

(但是dcast + cSplit會更有效率和可讀性)。