给出一个数据框的列,例如:
df <- structure(list(ingredients = structure(c("en:xylitol", "en:water,en:sugar,en:glucose-fructose-syrup,en:fructose,en:glucose,fr:dioxyde-de-carbone,en:acid,en:citric-acid,en:natural-flavouring,en:flavouring,fr:arome-quinine,fr:quinine",
"en:sugar,en:corn-syrup,fr:sirop-de-mais-a-teneur-elevee-en-fructose,en:citric-acid,en:natural-and-artificial-flavouring,en:artificial-flavouring,en:natural-flavouring,en:flavouring,en:colour,fr:rouge-40,fr:bleu-1",
"pt:semoule-de-ble-dur,pt:pesto,pt:basilic,pt:fromage-en-poudre,pt:ail-et-epinars,pt:basilic-contient-du-gluten-et-des-derives-de-lait",
"pt:pimenta-branca", "en:water,es:pasta-de-almendras-tostadas,en:sugar",
"en:water,es:zumo-de-chufas,en:sugar,en:dextrose,en:glucose,es:estabilizantes,es:412,es:carragenanos,es:e-407,es:carboximetil-celulosa,es:e-466,es:monodigliceridos-de-acidos-grasos,en:mono-and-diglycerides-of-fatty-acids,en:emulsifier,en:flavouring,en:guar-gum,es:e",
"es:aceitunas-cacerena,en:water,en:salt,en:stabiliser,es:579,es:categoria,es:i,es:calibre,es:gluconato-ferroso,es:e,es:240,es:260",
"en:carbonated-water,en:water,en:sugar,en:colour,fr:caramel-e150d,en:natural-flavouring,en:flavouring,en:acid,en:phosphoric-acid,fr:extrait-de-genepi,fr:cafeine",
"en:pear,en:fruit,es:variedad,es:70-mm,es:conferencia,es:categoria-i,es:calibre,es:65"
), .Dim = c(10L, 1L))), row.names = c(NA, -10L), class = c("tbl_df",
"tbl", "data.frame"))
我想用“,”分隔符分隔每一行,并将分隔的输出分组。
例如:
en:water,es:pasta-de-almendras-tostadas,en:sugar
将变成
group ingredient
1 en:water
1 es:pasta-de-almendras-tostadas
1 en:sugar
下一步是删除XX:
的前缀
请告知如何执行此操作?
答案 0 :(得分:3)
添加序列列后,我们可以使用separate_rows
中的tidyr
library(tidyr)
library(dplyr)
df %>%
mutate(group = row_number()) %>%
separate_rows(ingredients, sep=",")
答案 1 :(得分:2)
您可以使用strsplit
并根据列表编号添加一个组列,最后rbind
。
l <- strsplit(df$ingredients, ",")
res <- data.frame(do.call(rbind, sapply(seq(l), function(x)
cbind(group=x, ingredient=l[[x]]))))
head(res)
# group ingredient
# 1 1 en:xylitol
# 2 2 en:water
# 3 2 en:sugar
# 4 2 en:glucose-fructose-syrup
# 5 2 en:fructose
# 6 2 en:glucose
答案 2 :(得分:2)
以下是答案,包括删除前缀:
library(tidyverse)
df %>%
mutate(ingredients = str_split(ingredients, ","),
row_num = row_number()) %>%
unnest() %>%
mutate(ingredients = str_remove(ingredients, "^[^:]+(:)"))
#> # A tibble: 82 x 2
#> row_num ingredients
#> <int> <chr>
#> 1 1 xylitol
#> 2 2 water
#> 3 2 sugar
#> 4 2 glucose-fructose-syrup
#> 5 2 fructose
#> 6 2 glucose
#> 7 2 dioxyde-de-carbone
#> 8 2 acid
#> 9 2 citric-acid
#> 10 2 natural-flavouring
#> # … with 72 more rows
答案 3 :(得分:2)
我们可以使用data.table
:
require(data.table)
setDT(df)[, lapply(.SD, function(x){
unlist(tstrsplit(x, ",", fixed=TRUE))}),
by = seq.int(nrow(df))]
或仅使用base
:
stack(setNames(strsplit(df$ingredients,','), seq.int(nrow(df))))
或使用splitstackshape
软件包:
require(splitstackshape)
cSplit(cbind(seq.int(nrow(df)), df), "ingredients", ",", "long")
#> seq.int(nrow(df)) ingredients
#> 1: 1 en:xylitol
#> 2: 2 en:water
#> 3: 2 en:sugar
#> 4: 2 en:glucose-fructose-syrup
#> 5: 2 en:fructose
#> 6: 2 en:glucose
#...# … with 76 more rows (manually trimmed the output)
答案 4 :(得分:1)
使用@akrun建议的split_rows函数,我将以下代码与正则表达式^[a-z]{2}:
一起使用,这意味着我想在每个值的开头过滤前两个字符a-z
和一列(:
。
df %>%
dplyr::mutate(group = row_number()) %>%
tidyr::separate_rows(ingredients, sep = ",", convert = TRUE) %>%
dplyr::mutate(ingredients = str_remove(ingredients, pattern = "^[a-z]{2}:")) %>%
dplyr::distinct(ingredients, .keep_all = TRUE)