2017-01-01 51 views
1

寻找有关自动化我需要跨多个多种数据集执行的任务的帮助。基于列名称模式拆分数据框,然后重新绑定到1个数据框中

下面是一些示例数据:

#create example data 
x1_a<-rnorm(3) 
x1_b<-rnorm(3) 
x2_a<-rnorm(3) 
x2_b<-rnorm(3) 
x3_a<-rnorm(3) 
x3_b<-rnorm(3) 

df<-data.frame(x1_a, x1_b, x2_a, x2_b, x3_a, x3_b) 

> df 
     x1_a  x1_b  x2_a  x2_b  x3_a  x3_b 
1 0.2912428 1.2737063 -0.9997475 1.0400489 -0.5323241 -0.2229865 
2 2.0147965 -1.0180336 0.1080972 1.1411229 0.4791280 0.6230867 
3 0.4189106 -0.6987785 -0.3890773 -0.3292366 -1.6186305 1.3913514 

从本质上讲,这个数据是在宽格式,我需要它的长。但我不确定如何实现这种转换的自动化。

在此数据中,列中的数值表示该列所属的观察值(例如,x1_a与x1_b一起)。字符值指示列的实际内容。因此,匹配字符的列(例如,x1_a匹配x2_a,它们都是来自不同观察的“x_a”)是相同的,只是重复观察那个事物。

长格式数据只包含字符串变量(这里是“x_a”或“x_b”),并且包含重复的观察结果。我不知道原始数值是否保留。

我正在寻找的是一个自动化的方式来做到跨可变长度的数据集和不同的列名下面的代码(即所有符合“x1_a”的基本格局。

#laborious/embarassing, not good way to accomplish goal 
df1<-df[,c("x1_a", "x1_b")] 
names(df1)<-gsub("[[:digit:]]+", "", names(df1)) 
df2<-df[,c("x2_a", "x2_b")] 
names(df2)<-gsub("[[:digit:]]+", "", names(df1)) 
df3<-df[,c("x2_a", "x2_b")] 
names(df3)<-gsub("[[:digit:]]+", "", names(df1)) 

#desired data output 
df<-do.call(rbind, list(df1, df2, df3)) 
> df 
     x_a  x_b 
1 0.2912428 1.2737063 
2 2.0147965 -1.0180336 
3 0.4189106 -0.6987785 
4 -0.9997475 1.0400489 
5 0.1080972 1.1411229 
6 -0.3890773 -0.3292366 
7 -0.9997475 1.0400489 
8 0.1080972 1.1411229 
9 -0.3890773 -0.3292366 

我想像这样自动化的东西可能会工作:1)使用“grep”拉出与数值匹配的列名称(例如,x1_a与x1_b一起),2)对于有多少个唯一数值/组重复此操作,3 )将每个列名变量“拆分”到一个列表中,4)批量重命名这些列表元素中的列,以及5)将它们绑定回数据框。

链接到以前的帖子,如果我忽略了一些东西是值得欢迎的。预先感谢您的帮助!

回答

0

除了在此处的链接提供的答案是dplyr/tidyr解决方案:

library(dplyr) 
library(tidyr) 
gather(df, key, x) %>% 
    mutate(key = factor(grepl("_b", key), labels=c("x_a", "x_b"))) %>% 
    group_by(key) %>% 
    mutate(id=row_number()) %>% 
    spread(key, x) 
+0

伟大的作品!感谢您演示tidyr,而不是我熟悉的软件包。我参考了上面的其他帖子的链接,有一些很好的建议。我结束了在该帖子中的cbind解决方案,仅仅是因为这对我来说更直观。感谢您展示另一种方式来做到这一点,并指出我正确的方向! – griffmer

相关问题