Удаление строк во фрейме данных с помощью функции get
Предположим, у меня есть следующий фрейм данных:
mydataframe <- data.frame(ID=c(1,2,NA,4,5,NA),score=11:16)
Я хочу получить следующий кадр данных в конце:
mydataframe[-which(is.na(mydataframe$ID)),]
Мне нужно сделать этот вид очистки (и другие подобные манипуляции) со многими другими фреймами данных. Итак, я решил присвоить mydataframe имя и переменную интереса.
dbname <- "mydataframe"
varname <- "ID"
attach(get(dbname))
Я получаю сообщение об ошибке в следующей строке, по понятным причинам.
get(dbname) <- get(dbname)[-which(is.na(get(varname))),]
detach(get(dbname))
Как я могу решить это? (Я не хочу назначать новый фрейм данных, хотя сейчас это кажется единственным решением. Я буду использовать "dbname" много раз после этого.) Заранее спасибо.
4 ответа
Здесь нет get<-
функции, а нет get(colname)
функция (так как имена столбцов не являются объектами первого класса), но есть assign()
функция:
assign(dbname, get(dbname)[!is.na( get(dbname)[varname] ), ] )
Вы также не хотите использовать -which(.)
, Это сработало бы здесь, так как было несколько совпадений с условием. Однако он будет кусать вас, когда нет ни одной строки, которая соответствует, и вместо того, чтобы ничего не возвращать, как следует, он будет возвращать все, так как vec[numeric(0)] == vec
, Использовать только which
за "позитивный" выбор.
Как предполагает @Dason, списки составляются для такого рода работы.
Например:
# make a list with all your data.frames in it
# (just repeating the one data.frame 3x for this example)
alldfs <- list(mydataframe,mydataframe,mydataframe)
# apply your function to all the data.frames in the list
# have replaced original function in line with @DWin and @flodel's comments
# pointing out issues with using -which(...)
lapply(alldfs, function(x) x[!is.na(x$ID),])
Предложение использовать список фреймов данных является хорошим, но я думаю, что люди предполагают, что вы находитесь в ситуации, когда все фреймы данных загружаются одновременно. Это может не обязательно иметь место, например, если вы работаете над несколькими проектами и просто хотите, чтобы какой-то шаблонный код использовался во всех них.
Нечто подобное должно отвечать всем требованиям.
stripNAs <- function(df, var) df[!is.na(df[[var]]), ]
mydataframe <- stripNAs(mydataframe, "ID")
cars <- stripNAs(cars, "speed")
Я полностью понимаю вашу потребность в этом, поскольку мне также часто приходится циклически проходить через набор фреймов данных. Я считаю, что следующий код должен помочь вам:
mydataframe <- data.frame(ID=c(1,2,NA,4,5,NA),score=11:16)
#define target dataframe and varname
dbname <- "mydataframe"
varname <- "ID"
tmp.df <- get(dbname) #get df and give it a temporary name
col.focus <- which(colnames(tmp.df) == varname) #define the column of focus
tmp.df <- tmp.df[which(!is.na(tmp.df[,col.focus])),] #cut out the subset of the df where the column of focus is not NA.
#Result
ID score
1 1 11
2 2 12
4 4 14
5 5 15