Eu gostaria de pegar os dados do formulário
before = data.frame(attr = c(1,30,4,6), type=c('foo_and_bar','foo_and_bar_2'))
attr type
1 1 foo_and_bar
2 30 foo_and_bar_2
3 4 foo_and_bar
4 6 foo_and_bar_2
e use split()
na coluna " type
" acima para obter algo parecido com isto:
attr type_1 type_2
1 1 foo bar
2 30 foo bar_2
3 4 foo bar
4 6 foo bar_2
Eu vim com algo incrivelmente complexo envolvendo alguma forma de apply
que funcionou, mas desde então eu perdi isso. Parecia muito complicado para ser o melhor caminho. Posso usar strsplit
como abaixo, mas não sei como recuperar isso em duas colunas no quadro de dados.
> strsplit(as.character(before$type),'_and_')
[[1]]
[1] "foo" "bar"
[[2]]
[1] "foo" "bar_2"
[[3]]
[1] "foo" "bar"
[[4]]
[1] "foo" "bar_2"
Obrigado por qualquer indicação. Ainda não entendi muito bem as listas R.
left_right <- str_split_fixed(as.character(split_df),'\">',2)
str_split_fixed("aaa...bbb", fixed("..."), 2)
funciona bem comfixed()
"Corresponder a uma string fixa" nopattern=
argumento..
significa 'qualquer caractere' em regex.Outra opção é usar o novo pacote tidyr.
fonte
str_split_fixed
e adicionar colunas ao quadro de dados existente)?5 anos depois, adicionando a
data.table
solução obrigatóriaNós também poderia tanto ter certeza de que as colunas resultantes terão tipos corretos e melhorar o desempenho através da adição
type.convert
efixed
argumentos (desde"_and_"
não é realmente um regex)fonte
'_and_'
padrões variar, você poderá descobrir o número máximo de correspondências (futuras colunas) commax(lengths(strsplit(before$type, '_and_')))
strsplit
lo, ele cria um único vetor com 2 valores em cada slot, então otstrsplit
transpõe para 2 vetores com um único valor em cada um.paste0
é usado apenas para criar os nomes das colunas, não é usado nos valores. No LHS da equação estão os nomes das colunas, no RHS está a operação split + transpose na coluna.:=
significa " atribuir no local "; portanto, você não vê o<-
operador de atribuição lá.Ainda outra abordagem: use
rbind
emout
:E para combinar:
fonte
strcapture("(.*)_and_(.*)", as.character(before$type), data.frame(type_1 = "", type_2 = ""))
Observe que sapply com "[" pode ser usado para extrair o primeiro ou o segundo itens dessas listas, portanto:
E aqui está um método gsub:
fonte
aqui está um liner da mesma maneira que a solução da aniko, mas usando o pacote stringr de hadley:
fonte
stringr
pacote.Para adicionar às opções, você também pode usar minha
splitstackshape::cSplit
função assim:fonte
Uma maneira fácil é usar
sapply()
e a[
função:Por exemplo:
sapply()
O resultado é uma matriz e precisa ser transposta e lançada de volta para um quadro de dados. São algumas manipulações simples que produzem o resultado desejado:Neste ponto,
after
é o que você queriafonte
O assunto está quase esgotado, mas gostaria de oferecer uma solução para uma versão um pouco mais geral, na qual você não sabe a priori o número de colunas de saída. Então, por exemplo, você tem
Não podemos usar o dplyr
separate()
porque não sabemos o número das colunas de resultados antes da divisão, então criei uma função que usastringr
para dividir uma coluna, dado o padrão e um prefixo de nome para as colunas geradas. Espero que os padrões de codificação utilizados estejam corretos.Podemos então usar
split_into_multiple
em um tubo dplyr da seguinte maneira:E então podemos usar
gather
para arrumar ...fonte
Aqui está um liner básico R que se sobrepõe a várias soluções anteriores, mas retorna um data.frame com os nomes próprios.
Ele usa
strsplit
para dividir a variável edata.frame
comdo.call
/rbind
para colocar os dados novamente em um data.frame. A melhoria incremental adicional é o uso desetNames
para adicionar nomes de variáveis ao data.frame.fonte
Esta questão é bastante antiga, mas vou adicionar a solução que achei mais simples no momento.
fonte
Desde o R versão 3.4.0, você pode usar a
strcapture()
partir do pacote utils (incluído nas instalações R básicas), vinculando a saída às outras colunas.fonte
Outra abordagem que você deseja manter
strsplit()
é usar ounlist()
comando Aqui está uma solução nesse sentido.fonte
base, mas provavelmente lento:
fonte
Aqui está outra solução R básica. Podemos usar,
read.table
mas como ele aceita apenas umsep
argumento de um byte e aqui temos o separador de vários bytes, podemosgsub
substituir o separador de vários bytes por qualquer separador de um byte e usá-lo comosep
argumento emread.table
Nesse caso, também podemos torná-lo mais curto, substituindo-o pelo
sep
argumento padrão, para não precisarmos mencioná-lo explicitamentefonte