WebHU - Programozási kérdések és válaszok

Bármilyen értéket tartalmazó oszlopok gyors észlelése a grep segítségével

Van egy nagy adatkészletem, 5000 változó és 3 millió sorom. Meg akarom nézni, hogy mely oszlopok tartalmaznak dátumokat. A data.table fájllal dolgozom, és az adatokat a fread segítségével olvasom. A következőt futtatom, hogy megtudjam, mely oszlopok tartalmaznak dátumokat:

my[, lapply(.SD,function(xx) 
  length(grep("^\\d\\d?/\\d\\d?/\\d{4}$",xx))>0 ) ]

vagy ugyanez any(grepl())

De nagyon lassú.

Van valami mód gyorsabban megcsinálni? Lehet, hogy megállásra kényszeríti grep-et, amikor először találkozik randevúzással? Szerintem (parancssor) a grepnek van egy lehetősége erre:

grep -m 1

De szerintem R-ben nem elérhető.

Bármilyen ötlete? Az alap R-es vagy más csomagokkal rendelkező megoldásokat is szívesen fogadjuk.

A data.table csak néhány sorával is dolgozhatok, de egyes oszlopok nagyon kevés értéket tartalmazhatnak, amelyek eltérnek az NA-tól, és előfordulhat, hogy ezek hiányoznak.

Nagyon egyszerű példa néhány NA-val:

library(data.table)
set.seed(1)
siz <- 10000000
my <- data.table(
  AA=c(rep(NA,siz-1),"11/11/2001"),
  BB=sample(c("wrong", "11/11/2001"),siz, prob=c(1000000,1), replace=T),
  CC=sample(siz),
  DD=rep("11/11/2001",siz),
  EE=rep("HELLO", siz)
 )

Láttam, hogy létezik egy perl = FALSE opció, de nem tudom, hogy ez lehetővé teszi-e további paraméterek hozzáadását.

Vagy hasonlóképpen szeretném tudni, hogy a dátumnak vélt fájlok között vannak-e furcsa szimbólumok. Minden oszlopon futtathatnám a grep-et, de nagyon jó lenne, ha meg tudnám állni, amint a tesztem megfelelő lesz, anélkül, hogy az oszlop végéig folytatnám.

Esetleg valamilyen extra csomaggal, például stringivel?

02.10.2016

  • Azt hiszem, érdemes lenne néhány példaadatot generálni, amelyek illusztrálják az NA problémát. 02.10.2016
  • @Frank hozzáadtam. 02.10.2016
  • Hozzáadtam egy kérést az R-developmentnél, hogy kérjem az -m funkciót a grephez. De azt hiszem, évekbe fog telni. 02.10.2016
  • Próbáltam a stringi csomagból a stri_detect_regex-el, de lassabb. Arra számítottam, hogy lehetősége van arra, hogy megkeressen egy vektoron bármilyen előfordulást, majd leállítsa a folyamatot, de nincs is ilyen lehetősége. 02.10.2016

Válaszok:


1

Az egyik lehetőség az lenne, ha csak az első sort ellenőrizné (feltételezve, hogy ha van "Dátum" osztály, akkor azt veszi fel, hacsak az első nem hiányzó érték)

my[1][, grepl("\\d{2}/\\d{2}/\\d{4}", unlist(.SD))]

A fentieken túlmenően, ahogy @Frank említette, a teljes oszlopok helyett csak character osztályoszlopok egy részét ellenőrizhetjük a .SDcols megadásával

j1 <- sapply(my, is.character)
my[, lapply(.SD, function(x) 
            length(grep("\\d{2}/\\d{2}/\\d{4}", x))>1), 
              .SDcols = j1]

Benchmarkok

set.seed(24)
dat <- data.table(col1 = rnorm(1e6), col2 = "05/05/1942", 
      col3 = rnorm(1e6))

system.time(res <- dat[, lapply(.SD, function(x) 
                length(grep("\\d{2}/\\d{2}/\\d{4}", x))>1)])
# user  system elapsed 
#  6.33    0.01    6.35 

system.time(res2 <- dat[1][, grepl("\\d{2}/\\d{2}/\\d{4}", unlist(.SD))])
#   user  system elapsed 
#     0       0       0 


system.time({
  j1 <- sapply(dat, is.character)
  res3 <- dat[, lapply(.SD, function(x) 
     length(grep("\\d{2}/\\d{2}/\\d{4}", x))>1), .SDcols = j1]
  res3 <- names(dat) %in% names(res3)
     })
 #  user  system elapsed 
 #  0.43    0.00    0.44 



all.equal(unlist(res), res2, check.attributes = FALSE)
#[1] TRUE
all.equal(unlist(res), res3, check.attributes=FALSE) 
#[1] TRUE

Ha sok NA van, akkor az első sorban ellenőrizhetjük, ahol minden nem NA elem van

set.seed(24)
dat <- data.table(col1 = sample(c(NA, 1:10), 1e6, replace=TRUE),
     col2 = c(NA, "05/05/1942"),
     col3 = sample(c(NA, 1:5), 1e6, replace=TRUE))
dt1 <- head(dat, 20)
#Or just a sample of 20 rows from the dataset
#dt1 <- dat[sample(1:.N, 20, replace=TRUE)]
dt1[dt1[, which(!Reduce(`|`, lapply(.SD, is.na)))[1]]
     ][,  grepl("\\d{2}/\\d{2}/\\d{4}", unlist(.SD))]
02.10.2016
  • Talán .SDcols = sapply(dat, is.character) is beállítható, mivel a fread megpróbál számokat, egészeket stb. azonosítani (így általában nem minden col karakter, úgy értem). 02.10.2016
  • Mint mondtam, gyakran az első sor (és néha a legtöbb sor) tartalmaz egy NA-t. Az oszlopok fele karakteres (és legtöbbjük dátum lesz). 02.10.2016
  • Az oszlopdátumokat így szeretném észlelni, és később konvertálom posixct-re. 02.10.2016
  • @skan Ezután ellenőrizze, hogy van-e néhány olyan sor, ahol az összes elem nem NA, és tegye ezt az első sorban 02.10.2016
  • @skan Ennek a válasznak a variációja patt = "\\d{2}/\\d{2}/\\d{4}"; system.time( sapply(my, function(x) is.character(x) && length(grep(patt, unique(na.omit(x)))) ) ) kevesebb mint egy másodpercet vesz igénybe a számítógépemen a példádhoz. Nem biztos benne, hogy erre vágyik. 02.10.2016
  • Rendben, nagyon gyors az út, ha vannak NA-k, de most kaptam meg az igazi adatbázist, piszkos, és néha az NA-k nem NA-k, hanem bármilyen más szöveg. Átalakítom. 02.10.2016
  • @skan Nos, kezd olyan konkrét problémának tűnni, amivel csak te tudsz foglalkozni, de megpróbálhatod kiterjeszteni a példádat vagy feltenni egy új kérdést, ha úgy gondolod, hogy valaki többet tud segíteni. 02.10.2016
  • @skan Oké, ugyanazt az időzítést látom. És ha kiveszem a na.omit, akkor kicsit gyorsabb. 02.10.2016
  • @skan Frank módszerével user system elapsed 0.61 0.29 0.89-t kapok az új adatkészlethez. 02.10.2016
  • @skan Mert akkor a regex teszt csak egyedi értékekre vonatkozik. Mivel dátumokat néz, amelyek feltehetően nem ölelnek fel 100 évnél többet, azt várom, hogy kevesebb mint 30 000 egyedi értékkel rendelkezzen, ami sokkal rövidebb vektort jelent, mint az eredeti 10 millió 02.10.2016
  • @Frank , ha válaszát válaszlá alakítod, azt választom. a na.omit és az egyedi trükkök nagyon jók. Mindenesetre ez nem oldja meg a kezdeti kétségeimet, hogy hogyan kényszeríthetem leállásra a grep-et, amikor megtalálja az első előfordulást. (olyasmi, mint a grep -m 1). Gondolom, ha az R-t külső grep használatára kényszerítjük, az lassabb lesz. 02.10.2016
  • @skan Szerintem a minta a fő dolog, ezért írtam ide megjegyzést. Ha akrun vagy valaki más be akarja szerkeszteni a válaszába, akkor nekem rendben van. Nyitva hagyhatja a kérdést, és megnézheti, hogy valaki talál-e valami közelebbit a parancssori híváshoz. 02.10.2016
  • Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..