2017-09-14 75 views
6

datasets和各種軟件包帶有相當數量的有用數據集,但是當您需要它用於您的軟件包示例,用於教學目的或者要求/回答問題時,似乎沒有簡單的方法來找到您的完美數據集在這裏。如何找到具有某些特定屬性的數據集?

說例如我想要一個數據集是一個data.frame,至少有2 character列,並且少於100行。

如何探索每個可用的數據集並查看最多的相關信息以作出我的選擇?

我過去的嘗試很混亂,需要時間,並且碰到一些包含不尋常物體結構的軟件包,如caret

回答

2

擴展/修改自己的喜好。

library(data.table) 
dt = as.data.table(data(package = .packages(all.available = TRUE))$results) 
dt = dt[, `:=`(Item = sub(' \\(.*', '', Item), 
       Object = sub('.*\\((.*)\\)', '\\1', Item))] 

dt[, { 
     data(list = Object, package = Package) 
     d = eval(parse(text = Item)) 

     classes = if (sum(class(d) %in% c('data.frame')) > 0) unlist(lapply(d, class)) 
       else NA_integer_ 

     .(class = paste(class(d), collapse = ","), 
     nrow  = if (!is.null(nrow(d))) nrow(d) else NA_integer_, 
     ncol  = if (!is.null(ncol(d))) ncol(d) else NA_integer_, 
     charCols = sum(classes == 'character'), 
     facCols = sum(classes == 'factor')) 
    } 
    , by = .(Package, Item)] 
#  Package   Item            class nrow ncol charCols facCols 
# 1: datasets AirPassengers             ts NA NA  NA  NA 
# 2: datasets  BJsales             ts NA NA  NA  NA 
# 3: datasets BJsales.lead             ts NA NA  NA  NA 
# 4: datasets   BOD           data.frame 6 2  0  0 
# 5: datasets   CO2 nfnGroupedData,nfGroupedData,groupedData,data.frame 84 5  0  3 
# ---                          
#492: survival transplant           data.frame 815 6  0  3 
#493: survival  uspop2            array 101 2  NA  NA 
#494: survival  veteran           data.frame 137 8  0  1 
#495: viridis viridis.map           data.frame 1024 4  1  0 
#496: xtable   tli           data.frame 100 5  0  3 
+0

這是美麗的... –

+1

僅供參考我已將它改寫成我將使用的功能,請參閱我更新的答案。 –

1

在包datasets沒有data.frame類的數據集滿足您的條件,更確切地說,如果他們是data.frame類和至多100列,那麼他們都沒有character類的兩個或多個列。我剛剛發現了以下代碼的第一個版本。

library(datasets) 
res <- library(help = "datasets") 

dat <- unlist(lapply(strsplit(res$info[[2]], " "), '[[', 1)) 
dat <- dat[dat != ""] 
df_names <- NULL 
for(i in seq_along(dat)){ 
    d <- tryCatch(get(dat[i]), error = function(e) e) 
    if(inherits(d, "data.frame")){ 
     if(nrow(d) <= 100){ 
      char <- sum(sapply(d, is.character)) 
      fact <- sum(sapply(d, is.factor)) 
      if(char >= 2 || fact >= 2){ 
       print(dat[i]) 
       df_names <- c(df_names, dat[i]) 
      } 
     } 
    } 
} 

df_names 
[1] "CO2"  "esoph"  "npk"  "sleep"  "warpbreaks" 

所以我不得不包含額外的指令來處理類factor的列。默認情況下,使用stringsAsFactors = TRUE創建數據框。如果你能做到這一點,那麼你有它,他們的名字是矢量df_names。爲了讓它們在全球環境中可用,只需要get即可。

+0

好的謝謝你。我認爲如果沒有內置任何東西,我會圍繞它建立一個通用功能,並在此分享。就像一些data.frame中的數據集名稱,描述,類,長度,每個類的項目數量一樣。還有一個'data'函數可以返回可以限制到某些包的數據集,使用它可能會很有趣。但令我感到驚訝的是,我們看到的每個涉及日期的示例都是隨機瀏覽數百個數據集的列表或者像您一樣編寫自定義函數的結果。 –

3

我返工@ EDDI的kickass回答這樣:

  • 這是一個功能
  • 它不雜亂的工作空間(它只是加載data.table
  • 我改名列短,更增添了幾分
  • 列表元素的類也被檢查
  • 我返回對象和數據集標題
  • Annoyin G封裝的警告可以隱藏

你只是在運行這個(前提是你已經安裝data.table):

ds <- dataset_summary() # around 5 seconds if you have a lot of packages like me 

它的工作原理與使用有問題(見編輯歷史)的caret

subset(ds,Package == "caret") 
#  Package   Object    Item             Title  class nrow ncol char fact ord num int list df 
# 143 caret  GermanCredit  GermanCredit          German Credit Data data.frame 1000 62 0 1 0 54 7 0 0 
# 144 caret  Sacramento  Sacramento        Sacramento CA Home Prices data.frame 932 9 0 3 0 3 3 0 0 
# 145 caret   tecator   absorp   Fat, Water and Protein Content of Meat Samples  matrix 215 100 NA NA NA NA NA NA NA 
# 146 caret  BloodBrain   bbbDescr        Blood Brain Barrier Data data.frame 208 134 0 0 0 118 16 0 0 
# 147 caret    cars    cars Kelly Blue Book resale data for 2005 model year GM cars data.frame 804 18 0 0 0 1 17 0 0 
# 148 caret    cox2  cox2Class          COX-2 Activity Data  factor NA NA NA NA NA NA NA NA NA 

易子集,並尋找一個特定的數據集的list項目和data.frame列類計數。

subset(ds,class == 'list' & df > 0,select=-c(2,4)) 
#   Package   Item class nrow ncol char fact ord num int list df 
# 225  ecodist  iris.fit list NA NA 0 0 0 1 0 0 1 
# 238 ElemStatLearn orange10.test list NA NA 0 0 0 0 0 0 50 
# 239 ElemStatLearn orange10.train list NA NA 0 0 0 0 0 0 50 
# 240 ElemStatLearn orange4.test list NA NA 0 0 0 0 0 0 50 
# 241 ElemStatLearn orange4.train list NA NA 0 0 0 0 0 0 50 
# 346   lava missingdata list NA NA 0 0 0 0 0 0 4 

工作區是乾淨

ls() 
# [1] "dataset_summary" "ds" 

沒有從data.table加載開。

search() 
# [1] ".GlobalEnv"   "package:data.table" "package:Matrix"  "package:sp"   "package:timeSeries" "package:timeDate" 
# [7] "tools:rstudio"  "package:stats"  "package:graphics" "package:grDevices" "package:utils"  "package:datasets" 
# [13] "package:methods" "Autoloads"   "package:base" 

功能

dataset_summary <- function(silent = TRUE){ 
    if(silent){ 
    w <- options()$warn 
    options(warn = -1) 
    on.exit(options(warn = w)) 
    } 
    ws <- ls(envir=.GlobalEnv) 
    library(data.table) 
    dt = as.data.table(data(package = .packages(all.available = TRUE))$results) 
    dt = dt[, `:=`(Item = sub(' \\(.*', '', Item), 
       Object = sub('.*\\((.*)\\)', '\\1', Item))] 

    df <- as.data.frame(dt[, { 
    data(list = Object, package = Package) 
    d = eval(parse(text = Item)) 

    classes = if (sum(class(d) %in% c('data.frame','list')) > 0) unlist(lapply(d, class)) 
    else NA_integer_ 

    .(class = paste(class(d), collapse = ","), 
     nrow  = if (!is.null(nrow(d))) nrow(d) else NA_integer_, 
     ncol  = if (!is.null(ncol(d))) ncol(d) else NA_integer_, 
     char  = sum(classes == 'character'), 
     fact  = sum(classes == 'factor'), 
     ord  = sum(classes == 'ordered'), 
     num  = sum(classes == 'numeric'), 
     int  = sum(classes == 'integer'), 
     list  = sum(classes == 'list'), 
     df  = sum(classes == 'data.frame')) 
    } 
    , by = .(Package, Item)]) 
    rm(list=setdiff(ls(envir=.GlobalEnv),ws),envir=.GlobalEnv) 
    df 
} 
1

通過myfun()返回的表可以通過適當的條件下過濾,和數據集的列可通過其在類coulmn給定類進行鑑定。

caret包的問題是它沒有任何數據框或矩陣對象。數據集可以存在於列表對象內的caret中。我不確定,caret包中的一些列表對象包含一系列函數。

此外,如果感興趣,您可以使myfun()函數更具體地返回有關數據幀或矩陣對象的信息。

myfun <- function(package) 
{ 
    t(sapply(ls(paste0('package:', package)), function(x){ 
    y <- eval(parse(text = paste0(package, "::`", x, "`"))) 
    data.frame(data_class = paste0(class(y), collapse = ","), 
       nrow = ifelse(any(class(y) %in% c("data.frame", "matrix")), 
           nrow(y), 
           NA_integer_), 
       ncol = ifelse(any(class(y) %in% c("data.frame", "matrix")), 
           ncol(y), 
           NA_integer_), 
       classes = ifelse(any(class(y) %in% c("data.frame", "matrix")), 
            paste0(unlist(lapply(y, class)), collapse = ","), 
            NA), 
       stringsAsFactors = FALSE) 

    })) 
} 

library(datasets) 
meta_data <- myfun(package = "datasets") 
head(meta_data) 
#    data_class nrow ncol classes               
# ability.cov "list"  NA NA NA                
# airmiles  "ts"   NA NA NA                
# AirPassengers "ts"   NA NA NA                
# airquality "data.frame" 153 6 "integer,integer,numeric,integer,integer,integer"     
# anscombe  "data.frame" 11 8 "numeric,numeric,numeric,numeric,numeric,numeric,numeric,numeric" 
# attenu  "data.frame" 182 5 "numeric,numeric,factor,numeric,numeric" 

meta_data[ "ChickWeight", ] 
# $data_class 
# [1] "nfnGroupedData,nfGroupedData,groupedData,data.frame" 
# 
# $nrow 
# [1] 578 
# 
# $ncol 
# [1] 4 
# 
# $classes 
# [1] "numeric,numeric,ordered,factor,factor" 

library('caret') 
meta_data <- myfun(package = "caret") 
#    data_class nrow ncol classes 
# anovaScores "function" NA NA NA  
# avNNet  "function" NA NA NA  
# bag   "function" NA NA NA  
# bagControl "function" NA NA NA  
# bagEarth  "function" NA NA NA  
# bagEarthStats "function" NA NA NA 

如果加載的包需要應用myfun()功能上的包後卸載,試試這個:

loaded_pkgs <- search() 
library('caret') 
meta_data <- myfun(package = "caret") 
unload_pkgs <- setdiff(search(), loaded_pkgs) 
for(i in unload_pkgs) { 
    detach(pos = which(search() %in% i)) 
} 
+0

我真的很喜歡使用'ls('package:...')',因爲它可以訪問其他對象,這可以用來做更多的酷東西,比如通過正則表達式查找函數或者更多一點例如,通過參數查找功能。但它不會「看到」某些數據集,比如'caret'包中的數據集。 –

相關問題