2016-04-22 26 views
1

我有以下的數據幀:ř結合數據幀列與正則表達式

dat <- data.frame(
    c = c(1 , 2) , a1 = c(1 , 2) , a2 = c(3 , 4) , b1 = c(5 , 6) , b2 = c(7 , 8) 
) 
    c a1 a2 b1 b2 
1 1 1 3 5 7 
2 2 2 4 6 8 

即我想合併基於共享前綴列成爲該數據幀:

dat2 <- data.frame(
    c = c(1 , 2 , 1 , 2) , a = c(1 , 2 , 3 , 4) , b = c(5 , 6 , 7 , 8) 
) 
    c a b 
1 1 1 5 
2 2 2 6 
3 1 3 7 
4 2 4 8 

唯一我能想到的方式是嘗試使用melt()來做到這一點。這是我的嘗試:

melt(dat , measure.vars = c(grep("^a" , colnames(dat)) , grep("^b" , colnames(dat)))) 
    variable value 
1 1  a1  1 
2 2  a1  2 
3 1  a2  3 
4 2  a2  4 
5 1  b1  5 
6 2  b1  6 
7 1  b2  7 
8 2  b2  8 
> 

不用說,這是不正確。

+0

我覺得'融化'是一個很好的開始。現在您只需閱讀「dcast」的幫助頁面並完成該過程。 –

+0

有兩件事:使用dcast(data = dat,formula = value〜variable) '會讓我回到我所在的位置(理論上,我認爲,雖然它拋出一個錯誤,說它找不到「value」某些原因,但我似乎無法弄清楚如何去除變量的數字 – mnosefish

回答

2

我們可以使用meltdata.table這需要多個patternsmeasure

library(data.table) 
melt(setDT(dat), measure=patterns("^a\\d+", "^b\\d+"), 
        value.name=c("a", "b"))[, variable:= NULL][] 
# c a b 
#1: 1 1 5 
#2: 2 2 6 
#3: 1 3 7 
#4: 2 4 8 
+1

這是我能夠適應我的特定數據集的第一個。謝謝! – mnosefish

3
library(tidyr) 
library(dplyr) 

dat %>% 
    gather(key, value, -c) %>% # this gets you were you were... 
    separate(key, into = c("letter", "number"), sep = 1) %>% 
    spread(letter, value) %>% 
    select(-number) 
+0

我對tidyr的直到今天都完全不熟悉這個工作有多列,比如c,它不會是合併? – mnosefish

+0

是的,它會工作 – bramtayl

4

這是一個基地R的reshape實際上非常適合的情況。

reshape(dat, idvar="c", direction="long", sep="", varying=-1, timevar=NULL) 

# c a b 
#1.1 1 1 5 
#2.1 2 2 6 
#1.2 1 3 7 
#2.2 2 4 8 

sep=""本質上是告訴reshape()有組標識符(在這種情況下ab)和time指標之間沒有任何東西 - (在這種情況下12)在您的變量名。所以所有的重命名都是自動處理的。

reshape(dat, idvar="c", direction="long", sep="", varying=-1) 

# c time a b 
#1.1 1 1 1 5 
#2.1 2 1 2 6 
#1.2 1 2 3 7 
#2.2 2 2 4 8 

如果您有希望保持不變爲其他熔化的數據,那麼試試這個代碼中的許多ID變量:

如果我不設置timevar=NULL,以及它可能會更明顯:

# an example bit of data 
dat2 <- cbind(x=1:2,y=2:3,z=3:4, dat) 
dat2 

# x y z c a1 a2 b1 b2 
#1 1 2 3 1 1 3 5 7 
#2 2 3 4 2 2 4 6 8 

idv <- match(c("x","y","z","c"), names(dat2)) 
reshape(dat2, idvar=idv, direction="long", sep="", varying=-idv, timevar=NULL) 

#   x y z c a b 
#1.2.3.1.1 1 2 3 1 1 5 
#2.3.4.2.1 2 3 4 2 2 6 
#1.2.3.1.2 1 2 3 1 3 7 
#2.3.4.2.2 2 3 4 2 4 8 
+0

我喜歡這種方法。我遇到了'vary'的問題。如果我的前12列將被排除在整形之外(如'c'),我正在嘗試類似 - (data1,idvar = names(data1)[1:12],direction =「long」,sep =「」,vary = 1),但這是行不通的。 - (1:12),timevar = NULL) '。 – mnosefish

+0

這是最好的答案,imo。 Base R和地獄中的任何人都不知道如何使用'reshape()'。工作很好。 –

+0

@RichardScriven @我是一個擁有'reshape()'的人 - 它對我說話。 :-P – thelatemail