将字符字段中的多个值提取到新数据表中

时间:2015-10-05 14:43:33

标签: r dataframe

我的数据如下所示:

ids <- c(1,2,3)
titles <- c("Entry1", "Entry2", "Entry3")
tags <- c("<self-help><motivation>", "<programming><r><data.frame>", "<photography>")
df <- data.frame(id = ids, title = titles, tags = tags)
df

输出:

   id  title                         tags
1   1 Entry1      <self-help><motivation>
2   2 Entry2 <programming><r><data.frame>
3   3 Entry3                <photography>

我努力将标签提取到新的数据框中。我想要的是第二个数据框,如下所示:

  id         tag
1  1   self-help
2  1  motivation
3  2 programming
4  2           r
5  2  data.frame
6  3 photography

我已经设法使用以下内容使用列表某些,但结果列似乎以某种方式嵌套。我对unlist()的尝试要么没有效果,要么在结果向量中产生太多条目。

df$tags_list <- lapply(df$tags, function(x)strsplit(gsub("^.|.$", "", x), "><")[[1]])

我的问题是:有人可以帮我生成这个新显示的data.frame(或data.table} df,如此处所示?任何有关如何处理嵌套列表的智慧的话都非常受欢迎。

4 个答案:

答案 0 :(得分:9)

使用base R版本3.2.0+,您可以尝试:

lst <- strsplit(gsub("^<|>$", "", df$tags), split="><")
data.frame(id=rep(df$id, lengths(lst)), tags_list=unlist(lst))
#   id   tags_list
# 1  1   self-help
# 2  1  motivation
# 3  2 programming
# 4  2           r
# 5  2  data.frame
# 6  3 photography

使用gsub("^<|>$"..),我们消除了开头和终端括号,将模式"><"作为单词分隔符。然后我们使用id和分隔列表创建数据框。

<强>更新

在R 3.2.0中添加了函数lengths,并列出了length类似于向量的列表。在要求使用sapply(lst, length)之前。

答案 1 :(得分:4)

tidyr::unnest救援......

library(tidyr)
library(dplyr) # for %>%

df$tags2 <- strsplit(gsub("^.|.$", "", df$tags), "><")

df %>%
  unnest(tags2)

#   id  title                         tags       tags2
# 1  1 Entry1      <self-help><motivation>   self-help
# 2  1 Entry1      <self-help><motivation>  motivation
# 3  2 Entry2 <programming><r><data.frame> programming
# 4  2 Entry2 <programming><r><data.frame>           r
# 5  2 Entry2 <programming><r><data.frame>  data.frame
# 6  3 Entry3                <photography> photography

答案 2 :(得分:3)

您可以使用cSplit中的splitstackshape

library(splitstackshape)

cSplit(transform(df, tags=gsub('^<|>$','', tags)), 'tags', sep='><', direction='long')
#   id  title        tags
#1:  1 Entry1   self-help
#2:  1 Entry1  motivation
#3:  2 Entry2 programming
#4:  2 Entry2           r
#5:  2 Entry2  data.frame
#6:  3 Entry3 photography

答案 3 :(得分:1)

使用stri_extract_all library(stringi)melt

library(stringi) library(reshape2) melt(setNames(stri_extract_all_regex(df$tags, '[^<>]+'), df$id)) 的另一个选项
{{1}}