将列中的值分隔为多个列的名称和列值

时间:2017-08-04 09:57:31

标签: r rscript

我想将某个格式的数据从一列拆分为多列。以下是我的示例数据:

df = data.frame(id=c(1,2),data=c('apple:A%1^B%2^C%3_orange:A%1^B%2',
                                   'apple:A%1^B%2^D%3_orange:A%3^B%2'))
#    id    data
#    1    apple:A%1^B%2^C%3_orange:A%1^B%2
#    2    apple:A%1^B%2^D%3_orange:C%3^B%2

然后将提供以下输出

 id   data_apple_A  data_apple_B  data_apple_C  data_apple_D  data_orange_A  data_orange_B
 1       1               2              3                          1              2
 2       1               2                            3            1              2

我已经能够做到这一点但是我使用的方法涉及循环遍历每一行并通过每个分隔符执行str_split以获取每一行的数据并将其附加到最终输出数据帧考虑到我将在20输入列上有500k行,这是非常慢的。

我不认为我的for循环是一种正确的R方式来编写这个用例。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

我们可以将cSplitstr_extract

一起使用
library(splitstackshape)
library(zoo)
library(stringr)
dt <- cSplit(df, 'data', "\\^|_", fixed = FALSE, "long")[, c('grp', 'grp2', 'val') 
   := .(na.locf(str_extract(data, "^[A-Za-z]+(?=:)")), 
     str_extract(data, "[A-Z](?=[%])"), as.numeric(str_extract(data, "\\d+")))  ][]
dcast(dt, id ~ paste0("data_", grp) + grp2, value.var = 'val', sep = "_", fill = 0)
#    id data_apple_A data_apple_B data_apple_C data_apple_D data_orange_A data_orange_B
#1:  1            1            2            3            0             1             2
#2:  2            1            2            0            3             3             2