データフレームに問題があり、実際にその問題を解決できませんでした。
データフレーム arbitrary意的 列としてのプロパティ そして 各行 1を表します データセット。
質問は:
方法 列を削除します すべて 値はNAです?
これを試して:
df <- df[,colSums(is.na(df))<nrow(df)]
これまでに提供された2つのアプローチは、(他のメモリの問題とともに)is.na(df)
を作成するため、大きなデータセットでは失敗します。これはdf
と同じサイズのオブジェクトになります。
ここでは、より多くのメモリと時間の効率的な2つのアプローチを示します
Filter
を使用するアプローチ
Filter(function(x)!all(is.na(x)), df)
およびdata.tableを使用するアプローチ(一般的な時間とメモリ効率のため)
library(data.table)
DT <- as.data.table(df)
DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]
big_data <- replicate(10, data.frame(rep(NA, 1e6), sample(c(1:8,NA),1e6,T), sample(250,1e6,T)),simplify=F)
bd <- do.call(data.frame,big_data)
names(bd) <- paste0('X',seq_len(30))
DT <- as.data.table(bd)
system.time({df1 <- bd[,colSums(is.na(bd) < nrow(bd))]})
# error -- can't allocate vector of size ...
system.time({df2 <- bd[, !apply(is.na(bd), 2, all)]})
# error -- can't allocate vector of size ...
system.time({df3 <- Filter(function(x)!all(is.na(x)), bd)})
## user system elapsed
## 0.26 0.03 0.29
system.time({DT1 <- DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]})
## user system elapsed
## 0.14 0.03 0.18
dplyr
には、ここで役立つ可能性のあるselect_if
動詞があります。
library(dplyr)
temp <- data.frame(x = 1:5, y = c(1,2,NA,4, 5), z = rep(NA, 5))
not_all_na <- function(x) any(!is.na(x))
not_any_na <- function(x) all(!is.na(x))
> temp
x y z
1 1 1 NA
2 2 2 NA
3 3 NA NA
4 4 4 NA
5 5 5 NA
> temp %>% select_if(not_all_na)
x y
1 1 1
2 2 2
3 3 NA
4 4 4
5 5 5
> temp %>% select_if(not_any_na)
x
1 1
2 2
3 3
4 4
5 5
別の方法は、apply()
関数を使用することです。
Data.frameがある場合
df <- data.frame (var1 = c(1:7,NA),
var2 = c(1,2,1,3,4,NA,NA,9),
var3 = c(NA)
)
apply()
を使用して、どの列が条件を満たしているかを確認できます。したがって、apply
アプローチのみを使用して、Musaの回答と同じサブセットを実行できます。
> !apply (is.na(df), 2, all)
var1 var2 var3
TRUE TRUE FALSE
> df[, !apply(is.na(df), 2, all)]
var1 var2
1 1 1
2 2 2
3 3 1
4 4 3
5 5 4
6 6 NA
7 7 NA
8 NA 9
ゲームに遅れましたが、janitor
パッケージを使用することもできます。この関数は、すべてNAである列を削除し、すべてNAである行も削除するように変更できます。
df <- janitor::remove_empty(df, which = "cols")
df[sapply(df, function(x) all(is.na(x)))] <- NULL
受け入れられた回答は、数値以外の列では機能しません。 この回答 から、以下は異なるデータ型を含む列で動作します
Filter(function(x) !all(is.na(x)), df)
これも役立つことを願っています。単一のコマンドにすることもできますが、2つのコマンドに分割することで読みやすくなりました。私は次の指示で関数を作成し、非常に高速で作業しました。
naColsRemoval = function (DataTable) { na.cols = DataTable [ , .( which ( apply ( is.na ( .SD ) , 2 , all ) ) )] DataTable [ , unlist (na.cols) := NULL , with = F] }
.SDは、必要に応じてテーブルの一部に検証を制限することを許可しますが、テーブル全体を