Удаление строки и столбца частичного значения NA

У меня есть следующий фрейм данных (s):

s<-read.table(text = "V1    V2  V3  V4  V5  V6  V7  V8  V9  V10 
  1 0   62  64  44  NA  55  81  66  57  53  
  2 0   0   65  50  NA  56  79  69  52  55  
  3 0   0   0   57  NA  62  84  76  65  59  
  4 0   0   0   0   NA  30  70  61  41  36  
  5 0   0   0   0   NA  NA  NA  NA  NA  NA  
  6 0   0   0   0   0   0   66  63  51  44  
  7 0   0   0   0   0   0   0   80  72  72  
  8 0   0   0   0   0   0   0   0   68  64  
  9 0   0   0   0   0   0   0   0   0   47  
  10    0   0   0   0   0   0   0   0   0   0   ", header = TRUE)

Как видно, строка 5 и столбец 5 в этом случае включают только значения NA и 0. Я бы хотел их опустить и сохранить порядок строк и столбцов. В одном шаблоне может быть больше столбцов и строк, и я хотел бы сделать то же самое. Размер фрейма данных может быть изменен. Конечный результат будет:

    V1  V2  V3  V4  V6  V7  V8  V9  V10 
1   0   62  64  44  55  81  66  57  53  
2   0   0   65  50  56  79  69  52  55  
3   0   0   0   57  62  84  76  65  59  
4   0   0   0   0   30  70  61  41  36  
6   0   0   0   0   0   66  63  51  44  
7   0   0   0   0   0   0   80  72  72  
8   0   0   0   0   0   0   0   68  64  
9   0   0   0   0   0   0   0   0   47  
10  0   0   0   0   0   0   0   0   0   

Есть ли способ получить пропущенные номера строки и столбца (в данном случае 5)?


person Avi    schedule 26.04.2016    source источник
comment
Итак, каков минимальный номер NA, который оправдал бы сброс строки / столбца. Все ли значения, отличные от NA, должны быть равны 0, чтобы упасть?   -  person Serban Tanasa    schedule 26.04.2016
comment
Как видно, это матрица верхнего треугольника. В каждом случае NA будет для строк: от столбца с номером строки до последнего столбца (конец). И для того же номера столбца: от первой строки до того же номера строки (в данном примере 5)   -  person Avi    schedule 26.04.2016
comment
Это, вероятно, очевидно, но: вы должны использовать матрицу, а не data.frame.   -  person Frank    schedule 26.04.2016
comment
Я использую матрицу. Буду рад, если вы сможете показать ответ с вводом матрицы без необходимости конвертировать в dataframe.   -  person Avi    schedule 26.04.2016
comment
Есть ли способ получить пропущенные строку и столбец (в данном случае 5)?   -  person Avi    schedule 26.04.2016


Ответы (4)


Мы можем попробовать

v1 <- colSums(is.na(s))
v2 <- colSums(s==0, na.rm=TRUE)
j1 <- !(v1>0 & (v1+v2)==nrow(s) & v2 >0)

v3 <- rowSums(is.na(s))
v4 <- rowSums(s==0, na.rm=TRUE)
i1 <- !(v3>0 & (v3+v4)==ncol(s) & v3 >0)
s[i1, j1]
#   V1 V2 V3 V4 V6 V7 V8 V9 V10
#1   0 62 64 44 55 81 66 57  53
#2   0  0 65 50 56 79 69 52  55
#3   0  0  0 57 62 84 76 65  59
#4   0  0  0  0 30 70 61 41  36
#6   0  0  0  0  0 66 63 51  44
#7   0  0  0  0  0  0 80 72  72
#8   0  0  0  0  0  0  0 68  64
#9   0  0  0  0  0  0  0  0  47
#10  0  0  0  0  0  0  0  0   0

Предположим, если мы изменим одно из значений в 's'

 s$V7[3] <- NA

Запустив приведенный выше код, вывод будет

#   V1 V2 V3 V4 V6 V7 V8 V9 V10
#1   0 62 64 44 55 81 66 57  53
#2   0  0 65 50 56 79 69 52  55
#3   0  0  0 57 62 NA 76 65  59
#4   0  0  0  0 30 70 61 41  36
#6   0  0  0  0  0 66 63 51  44
#7   0  0  0  0  0  0 80 72  72
#8   0  0  0  0  0  0  0 68  64
#9   0  0  0  0  0  0  0  0  47
#10  0  0  0  0  0  0  0  0   0

ПРИМЕЧАНИЕ. Условие OP: включает только значения NA и 0. Я бы хотел их опустить.

person akrun    schedule 26.04.2016

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

Однако в целом это то, что я использую

s[!rowSums(is.na(s))>1,!colSums(is.na(s))>1]

Учитывая 0

s[!rowSums(is.na(s)|s==0)>9,!colSums(is.na(s)|s==0)>9]
person Ananta    schedule 26.04.2016

Я собирался предложить:

sclean <- s[rowSums(s == 0|is.na(s)) != ncol(s) | (rowSums(s == 0, na.rm=TRUE) == ncol(s)),
        colSums(s == 0|is.na(s) )!= nrow(s) | colSums(s == 0, na.rm=TRUE) == nrow(s)]
person Serban Tanasa    schedule 26.04.2016
comment
Я не думаю, что это правильно, поскольку ответ основан на значениях NA больше 1. У него может быть более одного NA с не-NA (кроме нулей). Например, если мы делаем s$V7[3] <- NA, он пропускает этот столбец, а мое решение сохраняет его. - person akrun; 26.04.2016
comment
@Avi Добавлено условие для сохранения 0 столбцов. - person Serban Tanasa; 26.04.2016
comment
@akrun, мое решение, похоже, сохраняет v7 в вашем тестовом примере. - person Serban Tanasa; 26.04.2016

Вы можете попробовать следующее:

myRowSums <- rowSums(is.na(s) | s == 0)
myColSums <- colSums(is.na(s) | s == 0)

sSmall <- s[which(myRowSums != ncol(s)), which(myColSums != nrow(s))]

Это работает для следующего набора данных, чтобы удалить все столбцы и строки, которые полностью состоят из нулей и NA.

s <- data.frame(a=c(0, rnorm(5), 0), b=c(0, rnorm(2), NA, NA,1, NA), c=c(rep(c(0,NA), 3), 0))
person lmo    schedule 26.04.2016
comment
попробуйте sSmall <- s[myRowSums != ncol(s), myColSums!= nrow(s)] - person Serban Tanasa; 26.04.2016
comment
Спасибо @SerbanTanasa. пришлось поработать пару опечаток. - person lmo; 26.04.2016