2017-08-11 59 views
2

我有两列作为数据帧:分裂一列分成多个列基于标记字符

**+-----+-------+ 
| V1 | V2  | 
+-----+---------+ 
| 1 | a,b,c | 
| 2 | a,c  | 
| 3 | b,d  | 
| 4 | e  | 
| . | .  | 
+-----+-------+** 

我要拆分的第二列到基于所述第二列内的标记字符的多个列。我希望输出如下。

**+-----+-------------+ 
| V1 | V2 | V3 | V4 | 
+-----+---------------+ 
| 1 | a | b | c | 
| 2 | a | c | NA | 
| 3 | b | d | NA | 
| 4 | e | NA | NA | 
| . | . | . | . | 
+-----+-------------+** 

这是this question的推广,但大小不平衡。例如下面的例子:

myVec <- c("F.US.CLE.V13", "F.US.CA6.U13", "F.US.CA6.U13","F.US.CA6", "F.US", "F") 

回答

5

或者你可以尝试这个包splitstackshape

cSplit(dat, 2, drop = TRUE,sep=',') 


    V1 V2_1 V2_2 V2_3 
1: 1 a b c 
2: 2 a c NA 
3: 3 b d NA 
4: 4 e NA NA 
+0

我认为这是最简单的。感谢所有人的快速回复。 – Rotail

+0

@罗塔尔很高兴帮助,美好的一天 – Wen

3

您可以使用data.table::tstrsplit

library(data.table) 
setDT(df)[, c(list(V1), tstrsplit(V2, ","))] 

# V1 V2 V3 V4 
#1: 1 a b c 
#2: 2 a c NA 
#3: 3 b d NA 
#4: 4 e NA NA 

myVec 
#[1] "F.US.CLE.V13" "F.US.CA6.U13" "F.US.CA6.U13" "F.US.CA6"  "F.US"   
#[6] "F"   

as.data.table(tstrsplit(myVec, '\\.')) 

# V1 V2 V3 V4 
#1: F US CLE V13 
#2: F US CA6 U13 
#3: F US CA6 U13 
#4: F US CA6 NA 
#5: F US NA NA 
#6: F NA NA NA 
4

您可以使用tidyrseparate功能

library(tidyr) 
DF <- data.frame(V1 = 1:4, V2 = c("a,b,c", "a,c", "b,d","e")) 
separate(DF, V2, into = c("V2", "V3", "V4")) 
#> Warning: Too few values at 3 locations: 2, 3, 4 
#> V1 V2 V3 V4 
#> 1 1 a b c 
#> 2 2 a c <NA> 
#> 3 3 b d <NA> 
#> 4 4 e <NA> <NA> 

如果你愿意,你可以取消此警告与fill参数

separate(DF, V2, into = c("V2", "V3", "V4"), fill = "right") 
#> V1 V2 V3 V4 
#> 1 1 a b c 
#> 2 2 a c <NA> 
#> 3 3 b d <NA> 
#> 4 4 e <NA> <NA> 
1

您可以使用dplyrtidyrdt2是最终输出。请注意0​​from tidyr可以工作,但是您需要知道事先要创建多少个列。这个解决方案不需要那个。

library(dplyr) 
library(tidyr) 

# Example data frame 
dt <- data_frame(V1 = 1:4, 
      V2 = c("a,b,c", "a,c", "b,d", "e")) 

# Process the data 
dt2 <- dt %>% 
    separate_rows(V2) %>% 
    rename(Value = V2) %>% 
    group_by(V1) %>% 
    mutate(Col = paste0("V", 1:n() + 1)) %>% 
    spread(Col, Value) 
0

如果你是OK写两行代码,为什么没有这种做法: 1)根据客户的特殊字符(逗号) 2)找到元素的最大数量您爆炸 3分割字符串)用可用元素准备一个表格,在需要时添加NA 4)结束并返回您的数据帧。

df <- cbind(1:5, c("a", "a,b,v", "a,c", "d,f,f", "ddd")) 
split.strings <- strsplit(df[,2], ",") 
# 
# get the max length 
max.elems <- max(sapply(split.strings, length)) 
# 
# wrap 
new.data <- sapply(1:max.elems, (function(i){ 
    sapply(1:nrow(df), (function(rw){ 
    if (length(split.strings[[rw]]) >= i) { 
     split.strings[[rw]][i] 
    } else { 
     NA 
    } 
    })) 
})) 
# 
# bind to identifier 
final.df <- data.frame(id = df[,1], 
         new.data, 
         stringsAsFactors = F) 
final.df