2017-08-10 20 views
0

我想从一列分割数据的某个格式转换成多列。下面是我的样本数据:分割成多发列按一定格式

df = data.frame(id=c(1,2),data=c('^apple:1%2%3^orange:3%4%5', 
            '^apple:4%5%6^orange:7%8%9')) 
# id data 
# 1 ^apple:1%2%3^orange:3%4%5 
# 2 ^apple:4%5%6^orange:7%8%9 

然后将给出以下输出

id data_apple_A data_apple_B data_apple_C data_orange_A data_orange_B data_orange_C 
1  1    2    3    3    4    5 
2  4    5    6    7    8    9 

我使用下面的代码,试图获得A,B和C的值(他们可能是小数值):

cSplit(df, "data", sep="\\^", fixed = FALSE,direction= "long")[, c('valA','valB','valC') 
     :=(str_extract(data, "\\d+\\.*\\d*")),str_extract(data, "(?<=%)\\d+\\.*\\d*"), 
     str_extract(data, "(?<=%)\\d+\\.*\\d*$") ][] 

但得到以下错误:

Error in `[.data.table`(cSplit(df, "data", sep = "\\^", fixed = FALSE, : 
    Provide either 'by' or 'keyby' but not both 

确实注意到,苹果和橘子只是一个占位符。它可以是字符,并且^(str):的数量也可以对于每一行是不同的。 另外,A B C是固定的。对于每个^(str):,只有3个十进制或非十进制数的格式为1%2%3。

任何帮助,将不胜感激。

+0

您可以使用库'tidyverse'。我不知道该怎么做的正是可是看看这个:HTTP://tidyr.tidyverse.org/reference/separate.html –

回答

1

下面是使用tidyr::extract一个解决方案:

library(tidyr) 
df %>% 
    extract(data, 
      into = paste(rep("data", 6), 
         c("apple", "orange"), 
         rep(c("A", "B", "C"), 2), sep = "_"), 
      regex = "\\^apple:([0-9])\\%([0-9])\\%([0-9])\\^orange:([0-9])\\%([0-9])\\%([0-9])") 
+0

的答案是完美的,我更喜欢像一个更全面的方式:'DF%>% (data,into = c(“apple”,“orange”),sep =“orange”)数据变换(数据= gsub(“\\^|:| apple”,“”,data))%>%> %>% separate(apple,into = paste(“apple”,LETTERS [1:3],sep =“_”),sep =“[%]”)%>% separate(orange,into = paste “橙色”,LETTERS [1:3],九月= “_”),九月= “[%]”)' – Jimbou

+0

我忘了提及,苹果和桔子只是占位符给出一个例子。在实际情况下,他们可能是任何东西,我需要能够接受任何东西。 A B C是固定的。 – kaexch