У меня большой набор данных, и я хотел бы прочитать определенные столбцы или отбросить все остальные.
data <- read.dta("file.dta")
Я выбираю столбцы, которые мне не интересны:
var.out <- names(data)[!names(data) %in% c("iden", "name", "x_serv", "m_serv")]
и чем я хотел бы сделать что-то вроде:
for(i in 1:length(var.out)) {
paste("data$", var.out[i], sep="") <- NULL
}
отбросить все ненужные столбцы. Это оптимальное решение?
subset(data, select=c(...))
помогает в моем случае для сбрасывания переменных. вопрос, однако, касался главным образомpaste("data$",var.out[i],sep="")
доступа к интересующим столбцам внутри цикла. Как я могу вставить или как-то составить имя столбца? Спасибо всем за ваше внимание и вашу помощьОтветы:
Вы должны использовать либо индексацию, либо
subset
функцию. Например :Затем вы можете использовать
which
функцию и-
оператор при индексации столбцов:Или, что намного проще, используйте
select
аргументsubset
функции: вы можете использовать-
оператор непосредственно для вектора имен столбцов и даже опустить кавычки вокруг имен!Обратите внимание, что вы также можете выбрать нужные столбцы, а не отбрасывать остальные:
источник
select
аргументsubset
функции сделали работу отлично! Спасибо, Джуба!which
не обязательно, см. ответ Исты. Но подмножество с-
это хорошо! Не знал этого!subset
выглядит хорошо, но способ, которым он молча отбрасывает пропущенные значения, кажется мне довольно опасным.subset
это действительно очень удобно, но не используйте его, если вы не используете R в интерактивном режиме. См. Предупреждение в документации по функции и этот вопрос SO для получения дополнительной информации.Не используйте
-which()
для этого, это крайне опасно. Рассматривать:Вместо этого используйте подмножество или
!
функцию:Я узнал об этом из мучительного опыта. Не злоупотребляйте
which()
!источник
setdiff
также полезно:setdiff(names(dat), c("foo", "bar"))
setdiff
Предложение @hadley очень хорошо для длинных списков имен.Во-первых , вы можете использовать прямую индексацию (с логическими векторами) вместо повторного доступа к именам столбцов, если вы работаете с одним и тем же фреймом данных; это будет безопаснее, как указывает Иста, и быстрее писать и выполнять. Так что вам нужно только:
а затем просто переназначить данные:
Во-вторых , быстрее написать, вы можете напрямую присвоить NULL столбцам, которые вы хотите удалить:
Наконец , вы можете использовать subset (), но его нельзя использовать в коде (об этом предупреждает даже файл справки). В частности, проблема для меня заключается в том, что если вы хотите напрямую использовать функцию удаления в susbset (), вам нужно написать без кавычек выражение, соответствующее именам столбцов:
В качестве бонуса приведем небольшой тест различных вариантов, который ясно показывает, что подмножество медленнее, а первый метод переназначения - быстрее:
Код ниже:
источник
NULL
, но почему, когда вы ставите более двух имен, необходимо назначить егоlist(NULL)
? Мне только интересно узнать, как это работает, потому что я пробовал только с одним именем, и мне не нужноlist()
$
или[[
), использование<- list(NULL)
приведет к неправильным результатам. Если вы обращаетесь к подмножеству фрейма данных с одним или несколькими столбцами,<- list(NULL)
этот путь можно использовать, даже если он не нужен для фрейма данных с одним столбцом (поскольку при необходимости онdf['myColumns']
будет приведен к вектору).Вы также можете попробовать
dplyr
пакет:источник
dplyr::select(df2, -one_of(c('x','y')))
прежнему будет работать (с предупреждением), даже если некоторые из названных столбцов не существуютВот быстрое решение для этого. Скажем, у вас есть фрейм данных X с тремя столбцами A, B и C:
Если я хочу удалить столбец, скажем B, просто используйте grep для colnames, чтобы получить индекс столбца, который затем можно использовать, чтобы опустить столбец.
Ваш новый фрейм данных X будет выглядеть следующим образом (на этот раз без столбца B):
Прелесть grep в том, что вы можете указать несколько столбцов, которые соответствуют регулярному выражению. Если бы у меня было X с пятью столбцами (A, B, C, D, E):
Выньте столбцы B и D:
РЕДАКТИРОВАТЬ: принимая во внимание предложение Мэтью Ландберг grepl в комментариях ниже:
Если я попытаюсь отбросить несуществующий столбец, ничего не произойдет:
источник
X[,-grep("B",colnames(X))]
не будет возвращать столбцы в случае, если имя столбца не содержитсяB
, вместо того, чтобы возвращать все столбцы, как хотелось бы. РассмотримX <- iris
для примера. Это проблема использования отрицательных индексов с вычисленными значениями. Рассмотримgrepl
вместо этого.Я пытался удалить столбец при использовании пакета
data.table
и получил неожиданный результат. Я думаю, что стоит написать следующее. Небольшое предостережение.[Под редакцией Мэтью ...]
По сути, синтаксис для
data.table
НЕ точно такой же, какdata.frame
. На самом деле существует множество отличий, см. FAQ 1.1 и FAQ 2.17. Вы были предупреждены!источник
DT[,var.out := NULL]
чтобы удалить столбцы, которые вы хотите сделать.data.frame
и для другихdata.table
Я изменил код на:
В любом случае, ответ Джубы - лучшее решение моей проблемы!
источник
select
аргументsubset
функции в моем коде. я просто хотел посмотреть, как я могу получить доступ к произвольным столбцам в цикле на случай, если я захочу сделать что-то еще, кроме простого удаления столбца. исходный набор данных имеет около 1200 переменных, и я заинтересован только в использовании 4 из них, не зная, где именно они находятся.Вот еще одно решение, которое может быть полезным для других. Код ниже выбирает небольшое количество строк и столбцов из большого набора данных. Столбцы выбраны, как в одном из ответов juba, за исключением того, что я использую функцию вставки, чтобы выбрать набор столбцов с именами, которые нумеруются последовательно:
источник
источник
Я не могу ответить на ваш вопрос в комментариях из-за низкой оценки репутации.
Следующий код выдаст вам ошибку, потому что функция вставки возвращает символьную строку
Вот возможное решение:
или просто сделайте:
источник
dfnum = df[,-c(8,9)]
источник