データフレームから数値列のみを選択する


189

次のようなdata.frameがあるとします。

x <- data.frame(v1=1:20,v2=1:20,v3=1:20,v4=letters[1:20])

xで数値である列のみをどのように選択しますか?

回答:


288

編集:不適切なアドバイスの使用を避けるために更新されましたsapply

データフレームはリストなので、list-apply関数を使用できます。

nums <- unlist(lapply(x, is.numeric))  

次に標準サブセット

x[ , nums]

## don't use sapply, even though it's less code
## nums <- sapply(x, is.numeric)

より慣用的な現代のRについては、今お勧めします

x[ , purrr::map_lgl(x, is.numeric)]

よりコードが少なく、Rの特定の癖をあまり反映せず、より単純で堅牢で、データベースバックエンドのチブルで使用できます。

dplyr::select_if(x, is.numeric)

10
x[nums]またはx[sapply(x,is.numeric)]同様に動作します。そして、彼らはいつも戻りdata.frameます。比較x[1]vs- x[,1]最初はdata.frame、2番目はベクトルです。変換を防止したい場合は、を使用する必要がありますx[, 1, drop=FALSE]
Marek、

連続データのみを選択する方法はありますか?このメソッドは、整数だけでなく連続も返します。
2016

数値列がない場合、以下のエラーが発生しundefined columns selectedます。どうやってそれを避けますか?
Yohan Obadia

@SoilSciGuyの連続データはas.numericである必要があります。おそらく、数値形式の因子データがありますか?新しい質問を開いてください。
Brandon Bertelsen

1
@YohanObadia a tryCatch()を使用してこれに対処できます。新しい質問を開くことを検討してください。
Brandon Bertelsen

79

dplyrパッケージのselect_if()関数はエレガントなソリューションです:

library("dplyr")
select_if(x, is.numeric)

44

Filter() ベースパッケージからはそのユースケースに最適な関数です:あなたは単にコーディングする必要があります:

Filter(is.numeric, x)

また、以下よりもはるかに高速ですselect_if()

library(microbenchmark)
microbenchmark(
    dplyr::select_if(mtcars, is.numeric),
    Filter(is.numeric, mtcars)
)

(私のコンピューターでは)の中央値は60マイクロ秒Filter、21 000マイクロ秒select_if(350倍高速)です。


このソリューションは、数値列が存在しない場合でも失敗しません。それを使用することに何か欠点はありますか?
BLI

フィルターは、列ではなくデータフレームの行にのみ適用されます。そのため、このソリューションでは正しい結果が得られません。
マイケル

4
@Michaelは、ベースパッケージのフィルターとdplyrパッケージのフィルターを混同しないでください。
ケビンザルカ2017

1
@bli Filterを使用することの欠点はわかりません。その入力はdata.frameオブジェクトであり、data.frameを返します
Kevin Zarca

参照のためにここでチャイムを鳴らすだけです。ここでFilter()機能しないのは、たとえば機能しないなどの置き換えFilter(is.numeric,iris) <- 0.5*Filter(is.numeric,iris)です。
Mobeus Zoom

8

列名だけに興味がある場合は、これを使用してください:

names(dplyr::select_if(train,is.numeric))



2

ライブラリPCAmixdataには、以下に示すように、特定のデータフレーム「YourDataframe」の量的(数値データ)と質的(カテゴリーデータ)を分割する機能splitmixがあります。

install.packages("PCAmixdata")
library(PCAmixdata)
split <- splitmix(YourDataframe)
X1 <- split$X.quanti(Gives numerical columns in the dataset) 
X2 <- split$X.quali (Gives categorical columns in the dataset)

2

別の方法は次のようになります:-

#extracting numeric columns from iris datset
(iris[sapply(iris, is.numeric)])

1
こんにちはAyushiさん、これはおそらく最初の回答の繰り返しであるため、反対票が投じられた可能性がありますが、この方法には特定されたいくつかの問題があります。最初の回答のコメントを見てください、私が何を意味するかわかります。
Brandon Bertelsen、2018年

1

多くの因子変数がある場合は、select_if関数を使用できます。dplyrパッケージをインストールします。条件を満たすことでデータを分離する機能はたくさんあります。条件を設定できます。

このように使います。

categorical<-select_if(df,is.factor)
str(categorical)

2
この以前の回答と同じように見えますstackoverflow.com/a/40808873/170352
Brandon Bertelsen 2017年

0

これは質問に直接答えることはできませんが、特にid列と従属変数を除くすべての数値列のようなものが必要な場合に非常に役立ちます。

numeric_cols <- sapply(dataframe, is.numeric) %>% which %>% 
                   names %>% setdiff(., c("id_variable", "dep_var"))

dataframe %<>% dplyr::mutate_at(numeric_cols, function(x) your_function(x))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.