我有两个数据框如下:
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并且它正在成功运行,但由于之后需要更多的手动处理,因此无法实现所需的结果。
期待听到有关完成上述工作的建议和方法。
感谢。
答案 0 :(得分:3)
我们可以使用data.table
和splitstackshape
执行此操作。使用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下面的方法非常简单,唯一的技巧是在合并NA
和df1
之后处理缺失值(即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)