将数据分成由tidyr中另一列给出的列

时间:2018-04-03 21:32:42

标签: r tidyr

我正在整理在单独的列中给出所需列名映射的数据,如下所示:

df <- data.frame(splitme = c("6, 7, 8, 9", "1,2,3"), 
                 type = c("A, B, C, D", "A, C, D"))

df看起来像:

     splitme       type
 6, 7, 8, 9       A, B, C, D
      1,2,3       A, C, D

所需的输出应如下所示:

desired_output <- data.frame(A = c(6,1), 
                             B = c(7, NA), 
                             C = c(8,2), 
                             D = c(9,3))

即:

  A  B C D
  6  7 8 9
  1 NA 2 3

如果不是因为某些行缺少类型这一事实,这对tidyr::separate来说是一个直截了当的任务。

## Not correctly aligned
df %>% 
tidyr::separate(splitme, into = c("A", "B", "C", "D")) %>% 
select(-type)

但很明显,对齐会带来问题。如果只有into参数可以采用指定拆分规则的列。也许有一个基于purr::pmap_df的策略可以在这里使用?

2 个答案:

答案 0 :(得分:5)

您可以使用separate_rows,然后使用spread

重塑
library(dplyr); library(tidyr);
df %>% 
    # add a row identification number for reshaping purpose
    mutate(rn = row_number()) %>% 
    separate_rows(splitme, type) %>% 
    spread(type, splitme) %>% 
    select(-rn)

#  A    B C D
#1 6    7 8 9
#2 1 <NA> 2 3

答案 1 :(得分:1)

使用purrr:map2_dfr,而不是解析splitme列,我们直接在data.frame调用中使用字符串。我们命名列,map2_dfr绑定行并处理mising值。

library(purrr)
map2_dfr(df$splitme,df$type,
         ~setNames(eval(parse(text=paste0("data.frame(",.x,")"))),
                   strsplit(.y,", ")[[1]]))
#   A  B C D
# 1 6  7 8 9
# 2 1 NA 2 3