Like answered by @Guilherme-Parreira use split
is the best way to separate the data by a variable:
dados <- data.frame(
comprar = c(rep("a",times = 4), rep("b",times = 4), rep("c",times = 4), rep("ab",times = 4), rep("ac",times = 4), rep("bc",times = 4)),
custo = c(12,14,16,18,22,24,26,28,17,19,21,23,34,36,38,42,44,46,48,52,62,64,66,68)
)
dados.lista <- split(dados, dados$comprar)
To select groups and associations, you can use a small function using strsplit
:
selGrp <- function(grp) c(strsplit(grp, "")[[1]], grp)
selGrp("abc")
#> [1] "a" "b" "c" "abc"
dados.lista[selGrp("ab")]
#> $a
#> comprar custo
#> 1 a 12
#> 2 a 14
#> 3 a 16
#> 4 a 18
#>
#> $b
#> comprar custo
#> 5 b 22
#> 6 b 24
#> 7 b 26
#> 8 b 28
#>
#> $ab
#> comprar custo
#> 13 ab 34
#> 14 ab 36
#> 15 ab 38
#> 16 ab 42
To do this for all associations:
# Níveis da variável comprar:
lv.comprar <- levels(dados$comprar)
# ou, se a variável comprar não for do tipo fator:
lv.comprar <- as.character(unique(dados$comprar))
# Encontra as associações (i.e., os valores que tem mais de um caracter):
assocs <- lv.comprar[nchar(lv.comprar) > 1]
# Cria uma lista nomeada em que cada elemento é uma lista com os data.frames selecionados de cada associação:
dados.spl <- setNames(lapply(assocs, function(x) dados.lista[selGrp(x)]), assocs)
str(dados.spl, max.level = 2)
#> List of 3
#> $ ab:List of 3
#> ..$ a :'data.frame': 4 obs. of 2 variables:
#> ..$ b :'data.frame': 4 obs. of 2 variables:
#> ..$ ab:'data.frame': 4 obs. of 2 variables:
#> $ ac:List of 3
#> ..$ a :'data.frame': 4 obs. of 2 variables:
#> ..$ c :'data.frame': 4 obs. of 2 variables:
#> ..$ ac:'data.frame': 4 obs. of 2 variables:
#> $ bc:List of 3
#> ..$ b :'data.frame': 4 obs. of 2 variables:
#> ..$ c :'data.frame': 4 obs. of 2 variables:
#> ..$ bc:'data.frame': 4 obs. of 2 variables:
dados.spl$ac
#> $a
#> comprar custo
#> 1 a 12
#> 2 a 14
#> 3 a 16
#> 4 a 18
#>
#> $c
#> comprar custo
#> 9 c 17
#> 10 c 19
#> 11 c 21
#> 12 c 23
#>
#> $ac
#> comprar custo
#> 17 ac 44
#> 18 ac 46
#> 19 ac 48
#> 20 ac 52
Keeping as list is the most versatile. If you want to convert the elements to data.frame:
# Formato comprido
dados.spl.comp <- lapply(dados.spl, data.frame)
dados.spl.comp$ac
#> a.comprar a.custo c.comprar c.custo ac.comprar ac.custo
#> 1 a 12 c 17 ac 44
#> 2 a 14 c 19 ac 46
#> 3 a 16 c 21 ac 48
#> 4 a 18 c 23 ac 52
# Formato longo
dados.spl.long <- lapply(dados.spl, function(x) do.call(rbind, x))
dados.spl.long$ac
#> comprar custo
#> a.1 a 12
#> a.2 a 14
#> a.3 a 16
#> a.4 a 18
#> c.9 c 17
#> c.10 c 19
#> c.11 c 21
#> c.12 c 23
#> ac.17 ac 44
#> ac.18 ac 46
#> ac.19 ac 48
#> ac.20 ac 52
Or, in a line:
setNames(lapply(assocs, function(x) do.call(rbind, dados.lista[selGrp(x)])), assocs)
setNames(lapply(assocs, function(x) data.frame(dados.lista[selGrp(x)])), assocs)