Использование 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]
Другие вопросы по тегам