数据操作 - 通过将值与另一个数据帧匹配来拆分和整形一个数据帧

时间:2016-09-08 17:33:47

标签: r string split

我有两个数据框如下:

DF1

ob         optcode
1 flora   gg,bb,cc, pb
2 alexa    tt,dd, pb
3 dixon      gg, cc

DF2

obname   type
1     gg orange
2     bb  apple
3     cc  nooption     
4     tt  grape
5     pb  nooption     
6     dd  melon

我正在做的是使用cSplit或strsplit函数分割df1中的'optcode'列,但是值应该进入df2中描述的相应列。因此,对于df1中的行-1,菌群在gg,bb,cc的optcode下具有三个值。应该拆分这些值,使得gg与df2中的类型匹配,然后列名称变为类型,'gg'作为值。其余的相同。结果应该是:

DF3

 ob        nooption    orange apple grape  melon
1 flora      cc, pb     gg     bb    none   none
2 alexa      pb        none   none    tt     dd
3 dixon      cc        gg   none   none   none 

另外需要注意的是,如果df2中没有optcode的类型,那么对于其余类型,应该有一个空字符串或NA或者不显示任何一个。应该有与列表类型一样多的列以及附加的选项列,其中如果没有与该值关联的类型,则填充值。希望这种解释是有道理的。

我在df1上尝试了cSplit并且它正在成功运行,但由于之后需要更多的手动处理,因此无法实现所需的结果。

期待听到有关完成上述工作的建议和方法。

感谢。

2 个答案:

答案 0 :(得分:3)

我们可以使用data.tablesplitstackshape执行此操作。使用cSplit中的splitstackshape,我们将' optcode'通过分隔符,long格式,然后是join on' optcode'使用' obname'从第二个数据集(' df2'),创建一个'选项'包含来自' optcode'的值的列其中'类型'为空("" - 我们将其指定为i)。使用dcast,转换“#”长期'广泛的'格式。

library(data.table)
d1 <- dcast(
        cSplit(df1, "optcode", ",", "long")[
           df2, on = c("optcode" ="obname")
             ][type == "", options := optcode], 
              ob + options ~type, value.var = "optcode")

按&#39; ob&#39;分组,我们删除每行的NA元素并指定(:=)附加列&#39; V1&#39;为NULL。

d1[, lapply(.SD, na.omit) , ob][, V1 := NULL][]
#      ob options apple grape melon orange
#1: alexa      NA    NA    tt    dd     NA
#2: dixon      pb    NA    NA    NA     NA
#3: flora      cc    bb    NA    NA     gg

数据

df1 <-  structure(list(ob = c("flora", "alexa", "dixon"), optcode = c("gg,bb,cc", 
"tt,dd", "pb")), .Names = c("ob", "optcode"), class = "data.frame", 
 row.names = c("1", "2", "3"))

df2 <- structure(list(obname = c("gg", "bb", "cc", "tt", "pb", "dd"), 
 type = c("orange", "apple", "", "grape", "", "melon")), .Names = c("obname", 
 "type"), class = "data.frame", row.names = c("1", "2", "3", "4", 
"5", "6"))

答案 1 :(得分:0)

这是一种tidyr / dplyr方法。 IMO下面的方法非常简单,唯一的技巧是在合并NAdf1之后处理缺失值(即df2&#39; s)。这是通过用"options"替换类型中的所有缺失条目,然后删除所有缺少的obname条目来完成的。

library(tidyr)
library(stringr)
library(dplyr)

df2[df2$type=="", "type"] = NA #replacing blanks with NA, we need for merger later

df1 %>% 
  separate(optcode, into = paste0("opt", seq(1, max(str_count(.$optcode, ",")) + 1)), sep=",") %>% #the code passed to the into argument is a bit overkill, however, it generalizes to any number of elements contained in optcode
  gather(key, obname, -ob) %>%
  left_join(df2) %>%
  select(-key) %>%
  mutate(type = ifelse(is.na(type), "options", type)) %>% 
  filter(!is.na(obname)) %>%
  spread(type,obname)