Eu tenho um grande conjunto de dados e gostaria de ler colunas específicas ou descartar todas as outras.
data <- read.dta("file.dta")
Eu seleciono as colunas nas quais não estou interessado:
var.out <- names(data)[!names(data) %in% c("iden", "name", "x_serv", "m_serv")]
e do que eu gostaria de fazer algo como:
for(i in 1:length(var.out)) {
paste("data$", var.out[i], sep="") <- NULL
}
para soltar todas as colunas indesejadas. Essa é a solução ideal?
subset(data, select=c(...))
ajuda no meu caso para deixar cair vars. a questão, porém, era principalmente sobre apaste("data$",var.out[i],sep="")
parte para acessar colunas de interesse dentro do loop. como colar ou de alguma forma compor um nome de coluna? Obrigado a todos por sua atenção e sua ajudaRespostas:
Você deve usar a indexação ou a
subset
função Por exemplo :Então você pode usar a
which
função e o-
operador na indexação de colunas:Ou, muito mais simples, use o
select
argumento dasubset
função: você pode usar o-
operador diretamente em um vetor de nomes de colunas e até omitir as aspas ao redor dos nomes!Observe que você também pode selecionar as colunas que deseja, em vez de soltar as outras:
fonte
select
argumento dasubset
função fez o trabalho perfeitamente! Obrigado juba!which
não é necessário, veja a resposta de Ista. Mas o subconjunto com-
é bom! Não sabia disso!subset
parece bom, mas a maneira como silenciosamente descarta os valores ausentes parece bastante perigosa para mim.subset
é realmente muito conveniente, mas lembre-se de evitar usá-lo, a menos que você esteja usando R interativamente. Consulte o aviso na documentação da função e esta pergunta SO para obter mais.Não use
-which()
para isso, é extremamente perigoso. Considerar:Em vez disso, use subconjunto ou a
!
função:Eu aprendi isso com uma experiência dolorosa. Não use demais
which()
!fonte
setdiff
também é útil:setdiff(names(dat), c("foo", "bar"))
setdiff
proposta de @hadley é muito boa para longas listas de nomes.Primeiro , você pode usar a indexação direta (com vetores booleanos) em vez de acessar novamente os nomes das colunas se estiver trabalhando com o mesmo quadro de dados; será mais seguro, como indicado por Ista, e mais rápido para escrever e executar. Então, o que você só precisará é:
e, em seguida, basta reatribuir dados:
Segundo , mais rápido de escrever, você pode atribuir NULL diretamente às colunas que deseja remover:
Por fim , você pode usar o subconjunto (), mas ele não pode realmente ser usado no código (mesmo o arquivo de ajuda avisa). Especificamente, um problema para mim é que, se você quiser usar diretamente o recurso drop de susbset (), precisará escrever sem aspas a expressão correspondente aos nomes das colunas:
Como bônus , aqui está uma pequena referência das diferentes opções, que mostra claramente que o subconjunto é o mais lento e que o primeiro método de reatribuição é o mais rápido:
O código está abaixo:
fonte
NULL
, mas por que quando você coloca mais de dois nomes é necessário atribuí-lalist(NULL)
? Eu só estou curioso para saber como ele funciona, porque eu tentei com apenas um nome e eu não precisolist()
$
ou[[
), o uso<- list(NULL)
levará a resultados incorretos. Se você acessar um subconjunto do quadro de dados com uma ou várias colunas,<- list(NULL)
é o caminho a seguir, mesmo que não seja necessário para um quadro de dados de uma coluna (porquedf['myColumns']
será convertido em um vetor, se necessário).Você também pode experimentar o
dplyr
pacote:fonte
dplyr::select(df2, -one_of(c('x','y')))
irá ainda trabalho (com um aviso), mesmo que algumas das colunas nomeadas não existemAqui está uma solução rápida para isso. Digamos que você tenha um quadro de dados X com três colunas A, B e C:
Se eu quiser remover uma coluna, digamos B, basta usar grep em colnames para obter o índice da coluna, que você poderá usar para omitir a coluna.
Seu novo quadro de dados X se pareceria com o seguinte (desta vez sem a coluna B):
A beleza do grep é que você pode especificar várias colunas que correspondem à expressão regular. Se eu tivesse X com cinco colunas (A, B, C, D, E):
Retire as colunas B e D:
EDIT: Considerando a sugestão grepl de Matthew Lundberg nos comentários abaixo:
Se eu tentar soltar uma coluna que não existe, nada deve acontecer:
fonte
X[,-grep("B",colnames(X))]
não retornará colunas no caso em que nenhum nome da coluna contenhaB
, em vez de retornar todas as colunas conforme desejado. Considere comX <- iris
um exemplo. Esse é o problema do uso de índices negativos com valores calculados. Considere emgrepl
vez disso.Tentei excluir uma coluna enquanto usava o pacote
data.table
e obtive um resultado inesperado. Eu acho que vale a pena postar o seguinte. Apenas uma pequena nota de advertência.[Editado por Matthew ...]
Basicamente, a sintaxe para
data.table
NÃO é exatamente a mesma quedata.frame
. De fato, existem muitas diferenças, consulte a FAQ 1.1 e a FAQ 2.17. Você foi avisado!fonte
DT[,var.out := NULL]
para excluir as colunas que deseja fazer.data.frame
edata.table
as classesEu mudei o código para:
Enfim, a resposta da juba é a melhor solução para o meu problema!
fonte
select
argumento dasubset
função no meu código. Eu só queria ver como eu poderia acessar colunas arbitrárias em um loop, no caso de eu querer fazer algo mais do que apenas soltar a coluna. o conjunto de dados original tem cerca de 1200 vars e só estou interessado em usar 4 deles sem saber exatamente onde estão.Aqui está outra solução que pode ser útil para outras pessoas. O código abaixo seleciona um pequeno número de linhas e colunas de um grande conjunto de dados. As colunas são selecionadas como em uma das respostas de juba, exceto pelo uso da função colar para selecionar um conjunto de colunas com nomes numerados sequencialmente:
fonte
fonte
Não posso responder à sua pergunta nos comentários devido à baixa pontuação na reputação.
O próximo código apresentará um erro porque a função colar retorna uma sequência de caracteres
Aqui está uma solução possível:
ou apenas faça:
fonte
dfnum = df[,-c(8,9)]
fonte