2014-11-07 2 views
1

Я хотел бы удалить столбцы со всеми нулями. Но некоторые столбцы имеют не числовые значения. Как удалить ненулевые столбцы и столбцы со всеми нулями. Было бы полезно, если бы было напечатано имя не числового столбца или номер столбца, поэтому я могу определить, было ли нормально удалять столбец.R Как проверить, есть ли столбец таблицы данных все нули

Вот что я пытаюсь, но это не работает, когда таблица данных имеет не числовые значения.

removeColsAllZeros = function(ddt) { 
    m <- as.matrix(ddt) 
    # isNumericColList <- lapply(1:ncol(m), function(ii,mm){is.numeric(mm[,ii])}, mm=m) 
    # indexNonNumericCols <- which(!unlist(isNumericColList)) 
    mnz <- m[, colSums(abs(m),na.rm = TRUE) != 0] 
    return(mnz) 
} 
+0

'unique (Col) == 0'? – Hugh

ответ

0

Ответы на оба ответа были полезны, но они не полностью ответили на вопрос. Вот функция для идентификации и удаления нечисловых и всех нулевых столбцов из таблицы данных. Это было полезно и обеспечило дополнительное понимание набора данных.

removeColsAllZeros = function(ddt) { 
    # Identify and remove nonnumeric cols and cols with all zeros 
    idx_all_zeros = ddt[, lapply(.SD, function(x){ (is.numeric(x) & all(x==0)) })] 
    idx_not_numeric = ddt[, lapply(.SD, function(x){ (!is.numeric(x)) })] 
    idx_all_zeros = which(unlist(idx_all_zeros)) 
    idx_not_numeric = which(unlist(idx_not_numeric)) 
    # Print bad column names 
    if (length(idx_all_zeros)>0) { 
    cat('Numeric columns with all zeros are\n',paste(names(ddt)[idx_all_zeros],collapse='\n'),'\n') 
    flush.console() 
    } 
    if (length(idx_not_numeric)>0) { 
    cat('Nonnumeric columns are\n',paste(names(ddt)[idx_not_numeric],collapse='\n'),'\n') 
    flush.console() 
    } 
    # Determine the numeric columns that have nonzero values 
    idx_bad = union(idx_all_zeros, idx_not_numeric) 
    idx_good = setdiff(seq(1,ncol(ddt)), idx_bad) 
    # Return nonzero numeric data 
    ddt[, names(ddt)[idx_good], with=FALSE] 
} 
3

Вот простая функция, которая может быть применена ко всем столбцам в кадре данных, возвращая только те, которые являются числовыми и не все равны нулю:

# Fake data 
dat = data.frame(x=rnorm(5), 
      y=rep(0,5), 
      z=sample(c(1,0),5,replace=TRUE), 
      w=sample(LETTERS[1:3],5,replace=TRUE), 
      stringsAsFactors=FALSE) 

dat 
      x y z w 
1 0.5450570 0 0 B 
2 0.5292899 0 0 B 
3 -0.2142306 0 1 C 
4 -0.7246841 0 0 C 
5 -0.7567683 0 1 A 

# Remove columns with all zeros or that are not numeric 
dat[, !sapply(names(dat), function(col) {all(dat[,col]==0) | 
              !is.numeric(dat[,col])})] 

      x z 
1 0.5450570 0 
2 0.5292899 0 
3 -0.2142306 1 
4 -0.7246841 0 
5 -0.7567683 1 

Для распаковки этого, функция проверяет, для одного столбца dat, имеет ли он все нули или не является числовым. sapply затем «применяет» эту функцию к каждому столбцу в кадре данных, возвращая логический вектор с TRUE для столбцов dat со всеми нулями или не численными и FALSE для столбцов, которые являются числовыми, а не всеми нулями. ! («НЕ») перед sapply просто меняет значения FALSE и TRUE:

!sapply(names(dat), function(col) { 
    all(dat[, col]==0) | !is.numeric(dat[, col]) 
    }) 

    x  y  z  w 
TRUE FALSE TRUE FALSE 

Затем мы используем этот логический вектор возвращать только те столбцы, которые datTRUE.

dat[ , c(TRUE, FALSE, TRUE, FALSE)] 

      x z 
1 0.5450570 0 
2 0.5292899 0 
3 -0.2142306 1 
4 -0.7246841 0 
5 -0.7567683 1 

Наконец, чтобы проверить, не числовые столбцы, которые были удалены, выполните следующие действия, которые будет возвращать все нецифровых столбцы:

dat[, sapply(names(dat), function(col) {!is.numeric(dat[,col])})] 
+0

Очень четкое объяснение. Я изучаю data.table сейчас, и я хотел бы задать вопрос. Я преобразовал данные в таблицу данных. 'setDT (dat) [,! sapply (names (dat), function (col) {all (dat [, col] == 0) |! is.numeric (dat [, col])})]'. Это возвращает логический вектор, включающий только FALSE. Это, наверное, простой вопрос, но я хотел бы знать, почему это произошло. Спасибо. – jazzurro

+0

Как этот подход можно изменить и для работы с таблицами данных? – user3969377

+0

@jazzurro: data.table возвращает имя столбца *, когда вы делаете 'dat [, col]', потому что col - это строка. Вы можете использовать 'dat [, col, with = FALSE]', чтобы использовать строку в качестве имени столбца, и это возвращает столбец, поэтому ваш 'all (dat [, col] == 0)' будет работать, но он возвращает столбец как * список *, а не вектор, поэтому 'is.numeric (dat [, col])' терпит неудачу. Вы можете использовать 'is.numeric (unlist (dat [, col, with = FALSE], use.names = FALSE)) вместо этого. Не уверен, насколько это эффективно, и мне было бы интересно узнать, есть ли более эффективное решение. – naught101

3

Это не компактная, но работает на таблицу данных после того, как изменяя код @ eipi10.

# toy data 
set.seed(1) 
dat = data.frame(x=rnorm(5), 
       y=rep(0,5), 
       z=sample(c(1,0),5,replace=TRUE), 
       w=sample(LETTERS[1:3],5,replace=TRUE), 
       stringsAsFactors=FALSE) 
# code for a data table 
library(data.table) 
setDT(dat) 
idx = dat[, lapply(.SD, function(x){ !(all(x==0) | !is.numeric(x)) })] 
dat[, names(dat)[unlist(idx)], with=FALSE] 
#    x z 
# 1: -0.6264538 1 
# 2: 0.1836433 1 
# 3: -0.8356286 0 
# 4: 1.5952808 1 
# 5: 0.3295078 0 
+0

Спасибо, мне нужно решение таблицы данных. Я буду ждать до завтра, чтобы оценить это решение с данными.Мне все еще нужны индексы столбцов всех нулевых или не числовых столбцов, которые могут быть idxout <-! (Idx% в% seq (1, ncol (dat))). Таблица данных содержит около 1200 столбцов, и мне нужно определить, откуда берутся не числовые столбцы. – user3969377

Смежные вопросы