Veri çerçevesinden yalnızca sayısal sütunları seçme


189

Diyelim ki böyle bir data.frame'iniz var:

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

Yalnızca x içindeki sayısal olan sütunları nasıl seçersiniz?

Yanıtlar:


289

EDIT: kötü tavsiye kullanımını önlemek için güncellendi sapply.

Veri çerçevesi bir liste olduğundan, listeye uygula işlevlerini kullanabiliriz:

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

Sonra standart alt ayar

x[ , nums]

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

Daha deyimsel bir modern R için şimdi tavsiye ederim

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

Daha az codey, R'nin belirli tuhaflıklarını daha az yansıtıyor ve daha basit ve veritabanı arka uçlu tibble'larda kullanımı daha sağlam:

dplyr::select_if(x, is.numeric)

10
x[nums]ya da x[sapply(x,is.numeric)]çalışıyor. Ve her zaman geri dönerler data.frame. Karşılaştır x[1]vs x[,1]- birincisi data.frame, ikincisi bir vektör. Bir dönüşüm önlemek istiyorsanız o zaman kullanmalısınız x[, 1, drop=FALSE].
Marek

Sadece sürekli veri seçmenin bir yolu var mı? Bu yöntem sürekli ve tamsayı döndürür.
Sahipsiz

Sayısal sütun yoksa, aşağıdaki hata ortaya çıkar undefined columns selected. Nasıl önlersiniz?
Yohan Obadia

@SoilSciGuy sürekli verisi sayısal olmalıdır. Belki de sayısal formdaki faktör verileriniz var mı? Yeni bir soru açmalısın.
Brandon Bertelsen

1
@YohanObadia Bununla tryCatch()başa çıkmak için bir kullanabilirsiniz . Lütfen yeni bir soru açmayı düşünün.
Brandon Bertelsen

79

Dplyr paketinin select_if() işlevi zarif bir çözümdür:

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

44

Filter() temel paketten bu kullanım durumu için mükemmel bir işlevdir: Sadece kodlamanız gerekir:

Filter(is.numeric, x)

Ayrıca aşağıdakilerden çok daha hızlıdır select_if():

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

(bilgisayarımda) için ortalama 60 mikrosaniye Filterve select_if21000 mikrosaniye (350 kat daha hızlı) döndürür.


Hiçbir sayısal sütun olmadığında bu çözüm başarısız olmaz. Kullanmanın sakıncaları var mı?
bli

Filtre, yalnızca sütunlardan ziyade bir veri çerçevesinin satırlarına uygulanır. Bu nedenle, bu çözüm doğru sonucu vermeyecektir.
Michael

4
@Michael Filtreyi temel paketten ve filtreyi dplyr paketinden karıştırmayın!
Kevin Zarca

1
@bli Filter kullanmanın herhangi bir dezavantajı göremiyorum.
Girdisi bir data.frame

Sadece burada referans için chiming: burada Filter()işe yaramayan değiştirmek, örneğin Filter(is.numeric,iris) <- 0.5*Filter(is.numeric,iris)işe yaramaz.
Mobeus Zoom

8

yalnızca sütun adlarıyla ilgileniyorsanız, bunu kullanın:

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

5

Bu diğer cevaplara alternatif bir kod:

x[, sapply(x, class) == "numeric"]

Birlikte data.table

x[, lapply(x, is.numeric) == TRUE, with = FALSE]

3
Bu, özgün cevaptan ziyade seçilen cevap için bir yorumdur.
Brandon Bertelsen

2
Sütunlar birden fazla sınıfa sahip olabilir.
Rich Scriven


2

PCAmixdata kütüphanesi, aşağıda gösterildiği gibi belirli bir veri karesi "YourDataframe" in nicel (Sayısal veri) ve nitel (Kategorik veriler) bölümünü ayıran functon splitmix'e sahiptir:

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

Başka bir yol şöyle olabilir:

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

1
Merhaba Ayushi, bu muhtemelen ilk cevabın tekrarı olduğu için indirildi, ancak bu yöntemin tanımlanmış bazı sorunları var. İlk cevaptaki yorumlara bir bakın, ne demek istediğimi göreceksiniz.
Brandon Bertelsen

1

Çok sayıda faktör değişkeniniz varsa, fonksiyonu kullanabilirsiniz select_if. dplyr paketlerini kurun. Bir koşulu karşılayarak verileri ayıran birçok işlev vardır. koşulları ayarlayabilirsiniz.

Bunun gibi kullan.

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

2
Bu daha önceki cevabın kopyası gibi görünüyor stackoverflow.com/a/40808873/170352
Brandon Bertelsen

0

Bu doğrudan soruyu cevaplamaz, ancak özellikle id sütununuz ve bağımlı değişkeniniz dışında tüm sayısal sütunlar gibi bir şey istiyorsanız çok yararlı olabilir.

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))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.