Использование 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"

В идеале я хочу, чтобы он дал мне векторный СПИСОК всех имен столбцов, где процент всех нулевых переменных (NA, -999, 0, NULL) превышает 30%.

Кто-нибудь может помочь?


person Matthew Rittinghouse    schedule 02.06.2015    source источник
comment
lapply не нужен MARGIN. Это для apply. Вы можете проверить примеры в ?lapply   -  person akrun    schedule 02.06.2015


Ответы (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]
person yuanhangliu1    schedule 02.06.2015
comment
Спасибо большое. Мое окончательное решение было следующим: null_counts ‹- apply(indata, 2, function(x) length(what(x == | is.na(x) | x == NA | x == -999 | x == 0)) ) null_flags ‹- имена столбцов (indata [который (0,5‹ = null_counts/nrow (indata))]) - person Matthew Rittinghouse; 02.06.2015

Вот другой способ сделать это в 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]
person MichaelChirico    schedule 03.06.2015