2016-01-13 35 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会更有效率和可读性)。