Eu tenho um monte de colunas em um dataframe que quero colar (separadas por "-") da seguinte maneira:
data <- data.frame('a' = 1:3,
'b' = c('a','b','c'),
'c' = c('d', 'e', 'f'),
'd' = c('g', 'h', 'i'))
i.e.
a b c d
1 a d g
2 b e h
3 c f i
O que eu quero me tornar:
a x
1 a-d-g
2 b-e-h
3 c-f-i
Eu normalmente poderia fazer isso com:
within(data, x <- paste(b,c,d,sep='-'))
e depois removendo as colunas antigas, mas infelizmente não sei os nomes das colunas especificamente, apenas um nome coletivo para todas as colunas, por exemplo, eu saberia que cols <- c('b','c','d')
Alguém conhece uma maneira de fazer isso?
do.call
?evil(parse(...))
, por exemplo , mas acredito quedo.call
é a opção certa aqui.collapse = "-"
? parapaste
?Como uma variante da resposta de Baptiste , com
data
definido como você tem e as colunas que você deseja juntar definidas emcols
Você pode adicionar a nova coluna
data
e excluir as antigas comque dá
fonte
data.frame
com um vetor de um único caractere será uma indexação de coluna, apesar de o primeiro argumento geralmente ser o índice de linha.Usando o
tidyr
pacote, isso pode ser facilmente tratado em 1 chamada de função.Editar: exclui a primeira coluna, todo o resto é colado.
fonte
within(data, x <- paste(b,c,d,sep='-'))
conforme ilustrado.unite_(data, "b_c_d", cols)
sim, ou dependendo de seu data.frame real,unite(data, b_c_d, -a)
pode ser um candidato também.Eu construiria um novo data.frame:
fonte
d[ , cols]
você pode querer usard[ , names(d) != 'a']
se todas, exceto aa
coluna, forem coladas juntas.cbind(a = d['a'], x = do.call(paste, c(d[cols], sep = '-')))
, por exemplo, evitar as vírgulaslist
edata.frame
ao usar odata.frame
método decbind
Apenas para adicionar solução adicional com a
Reduce
qual provavelmente é mais lenta do que,do.call
mas provavelmente melhor do queapply
porque evitará amatrix
conversão. Além disso, em vez disso,for
podemos usar apenas um loopsetdiff
para remover colunas indesejadasAlternativamente, podemos atualizar
data
no local usando odata.table
pacote (assumindo dados novos)Outra opção é usar
.SDcols
, em vez demget
como emfonte
Eu comparei as respostas de Anthony Damico, Brian Diggs e data_steve em uma pequena amostra
tbl_df
e obtive os seguintes resultados.No entanto, quando avaliei sozinho
tbl_df
com ~ 1 milhão de linhas e 10 colunas, os resultados foram bastante diferentes.fonte
Na minha opinião, a
sprintf
função -f merece um lugar entre essas respostas também. Você pode usarsprintf
o seguinte:que dá:
E para criar o dataframe necessário:
dando:
Embora
sprintf
não tenha uma vantagem clara sobre a combinaçãodo.call
/paste
de @BrianDiggs, é especialmente útil quando você também deseja preencher certas partes da string desejada ou quando deseja especificar o número de dígitos. Veja?sprintf
para as várias opções.Outra variante seria usar
pmap
deronronar:Nota: esta
pmap
solução só funciona quando as colunas não são fatores.Uma referência em um conjunto de dados maior:
resulta em:
Dados usados:
fonte
Esta é uma abordagem pouco convencional (mas rápida): use
fwrite
dedata.table
para "colar" as colunas efread
para lê-las de volta. Para sua conveniência, escrevi as etapas como uma função chamadafpaste
:Aqui está um exemplo:
Como funciona?
fonte
TMPDIR=/dev/shm R
), mas não noto uma grande diferença em comparação a esses resultados. Eu também não brinquei com o número de threads usadosfread
oufwrite
para ver como isso afeta os resultados.fonte
Eu sei que esta é uma questão antiga, mas pensei que deveria de qualquer maneira apresentar a solução simples usando a função paste (), conforme sugerido pelo questionador:
fonte