2016-04-22 82 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