Удалить постоянные столбцы с или без NA

Я пытаюсь заставить много моделей lm работать в функции, и мне нужно автоматически отбрасывать постоянные столбцы из моей таблицы данных. Таким образом, я хочу сохранить только столбцы с двумя или более уникальными значениями, исключая NA из count.

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

Мой воспроизводимый код:

library(data.table)
df <- data.table(x=c(1,2,3,NA,5), y=c(1,1,NA,NA,NA),z=c(NA,NA,NA,NA,NA), 
d=c(2,2,2,2,2))

> df
    x  y  z d
1:  1  1 NA 2
2:  2  1 NA 2
3:  3 NA NA 2
4: NA NA NA 2
5:  5 NA NA 2

Мое намерение состоит в том, чтобы удалить столбцы y, z и d, поскольку они являются константами, включая y, которые имеют только одно уникальное значение, когда NA опущены.

Я пробовал это:

same <- sapply(df, function(.col){ all(is.na(.col))  || all(.col[1L] == .col)})
df1 <- df[ , !same, with = FALSE]


> df1
    x  y
1:  1  1
2:  2  1
3:  3 NA
4: NA NA
5:  5 NA

Как видно, 'y' все еще существует... Любая помощь?

Ответ 1

Поскольку у вас есть data.table, вы можете использовать uniqueN и его аргумент na.rm:

df[ , lapply(.SD, function(v) if(uniqueN(v, na.rm = TRUE) > 1) v)]
#     x
# 1:  1
# 2:  2
# 3:  3
# 4: NA
# 5:  5

Альтернативой

A base может быть Filter(function(x) length(unique(x[!is.na(x)])) > 1, df)

Ответ 2

В базе r существует простое решение с функцией Filter. Это поможет.

library(data.table)
df <- data.table(x=c(1,2,3,NA,5), y=c(1,1,NA,NA,NA),z=c(NA,NA,NA,NA,NA), 
                 d=c(2,2,2,2,2))
# Select only columns for which SD is not 0
> Filter(function(x) sd(x, na.rm = TRUE) != 0, df)
    x
1:  1
2:  2
3:  3
4: NA
5:  5

Примечание. Не забудьте использовать na.rm = TRUE.

Ответ 3

Вот вариант:

df[,which(df[,
       unlist(
        sapply(.SD,function(x) length(unique(x[!is.na(x)])) >1))]),
   with=FALSE]

    x
1:  1
2:  2
3:  3
4: NA
5:  5

Для каждого столбца таблицы данных мы подсчитываем количество уникальных значений, отличных от NA. Мы сохраняем только столбец с несколькими значениями.

Ответ 4

Проверьте, равна ли дисперсия нулю:

df[, sapply(df, var, na.rm = TRUE) != 0, with = FALSE]
#     x
# 1:  1
# 2:  2
# 3:  3
# 4: NA
# 5:  5

Ответ 5

Просто измените

all(is.na(.col)) || all(.col[1L] == .col)

to

all(is.na(.col) | .col[1L] == .col)

Конечный код:

same <- sapply( df, function(.col){ all( is.na(.col) | .col[1L] == .col ) } )
df1 <- df[,!same, with=F]

Результат:

    x
1:  1
2:  2
3:  3
4: NA
5:  5

Ответ 6

Если вы действительно имеете в виду DROPing этих столбцов, вот решение:

library(data.table)
dt <- data.table(x=c(1,2,3,NA,5), 
                 y=c(1,1,NA,NA,NA),
                 z=c(NA,NA,NA,NA,NA), 
                 d=c(2,2,2,2,2))

for (col in names(copy(dt))){
    v = var(dt[[col]], na.rm = TRUE)
    if (v == 0 | is.na(v)) dt[, (col) := NULL]
}