2017-08-07 54 views
0

我有一个格式来分离,其中我将有这样的数据:柱拆分

df = data.frame(id=c(1,2),name=c('A~B~C','A~B~D'),value=c('1~2~3','1~~2')) 
id name  value 
1 A~B~C  1~2~3 
2 A~B~D  1~~2 

从而有望具有以下输出,其中列名是原始列名,后跟文本在名称列:

id value_A value_B value_C value_D 
1  1   2   3  
2  1       2 

我设法通过使用许多嵌套的for循环来对我行的数据行处理以实现分裂。它适用于小样本数据,但一旦数据变大,时间就成了问题。

此外,可能有多个值列,但它们都应映射到同一名称列中。 输出示例:

id value_A value_B value_C value1_A value1_B value1_C 
1  1   2   3  1   2   3 
2  1   2   3  1   2   3 

回答

0

这是一个使用cSplit/dcast的选项。与cSplitdcast以“宽”格式

library(splitstackshape) 
dcast(cSplit(df, c('name','value'), '~', 'long')[!is.na(value)], id ~ paste0('value_', name)) 
# id value_A value_B value_C value_D 
#1: 1  1  2  3  NA 
#2: 2  1  NA  NA  2 
+0

如果让我说我有一个value1和value2列。我可以对''dcast'做些什么改变来使其能够投射这些值?我知道我可以使用'cSplit(df,c('name','value1','value2'),'〜','long')'分割3列。 – kaexch

2

您可以尝试dplyr

library(tidyverse) 
df %>% 
separate_rows(name, value, sep = "~") %>% 
spread(name, value) 
    id A B C D 
1 1 1 2 3 <NA> 
2 2 1 <NA> 2 

NA相反,你可以填补空白单元格的事情,你内fill = ""

或者卑劣和reshape2注明:

a <- strsplit(as.character(df$name), "~") 
b <- strsplit(as.character(df$value), "~") 
df2 <- do.call(rbind.data.frame, Map(cbind, df$id, a, b)) 
library(reshape2) 
dcast(df2, V1~V2, value.var = "V3") 
    A B C D 
1 1 2 3 <NA> 
2 1 <NA> 2 
+0

有什么办法追加VALUE_(原列名)到每一列的拆分行到“长”格式? – kaexch

+0

托盘在第一个例子'select(id,value_A = A,value_B = B,value_C = C,value_D = D)中加入这个或者重命名结果data.frame(例如保存到变量'df1') colnames(df1)[ - 1] < - paste0(“value_”,colnames(df1)[ - 1])' – Jimbou