Использование lapply для отображения процента пустых переменных в каждом столбце в R
Мне дали большой CSV, который составляет 115 столбцов в поперечнике и 1000 строк. Столбцы содержат различные данные, некоторые основаны на символах, некоторые целочисленные и т. Д. Однако в данных содержится МНОЖЕСТВО пустых переменных разных типов (NA, -999, NULL и т. Д.).
Что я хочу сделать, это написать скрипт, который будет генерировать список столбцов, где более 30% данных в столбце является NULL некоторого типа.
Чтобы сделать это, я написал скрипт, который дает мне нулевой процент (в десятичном виде) для одного столбца. Этот скрипт прекрасно работает для меня.
length(which(indata$ObservationYear == "" | is.na(indata$ObservationYear) |
indata$ObservationYear == "NA" | indata$ObservationYear == "-999" |
indata$ObservationYear == "0"))/nrow(indata)
Я хочу написать сценарий, чтобы сделать это для всех столбцов. Я считаю, что мне нужно использовать функцию lapply.
Я попытался сделать это здесь, однако, я не могу заставить этот скрипт работать вообще:
Null_Counter <- lapply(indata, 2, length(x),
length(which(indata == "" | is.na(indata) | indata == "NA" | indata == "-999" | indata == "0")))
names(indata(which(0.3>=Null_Counter / nrow(indata))))
Я получаю следующие ошибки:
Error in match.fun(FUN) : '2' is not a function, character or symbol
а также:
Error: could not find function "indata"
В идеале, я хочу, чтобы это был векторный LIST всех имен столбцов, где процент всех нулевых переменных (NA, -999, 0, NULL) превышает 30%.
Кто-нибудь может помочь?
2 ответа
Я полагаю, что вы хотите использовать apply, а не lapply, чтобы применить функцию к списку. Попробуй это:
Null_Counter <- apply(indata, 2, function(x) length(which(x == "" | is.na(x) | x == "NA" | x == "-999" | x == "0"))/length(x))
Null_Name <- colnames(indata)[Null_Counter >= 0.3]
Вот другой способ сделать это в data.table
:
#first, make a reproducible example:
library(data.table)
#make it so that all columns have ~30% "NA" as you define it
dt<-as.data.table(replicate(
115,sample(c(1:100,"",NA,"NA",-999,0),size=1000,replace=T,
prob=c(rep(.007,100),rep(.06,5)))))
Теперь выясните, какие проблемы:
x<-as.matrix(dt[,lapply(.SD,function(x){
mean(is.na(x) | x %in% c("","NA","-999","0"))})])
colnames(x)[x>.3]
Возможно, есть более краткий способ сделать это, но это ускользает от меня.
Если вы пытаетесь удалить эти столбцы, это можно изменить:
dt[,!colnames(x)[x>.3],with=F]