Zastąp wiele wartości w kolumnie tabeli danych po wielokrotnym dopasowaniu do wzorca

Nov 22 2020

Oto fragment, który może pomóc kilku `` początkującym w R '', takim jak ja: odnosiłem się do tego wątku dla potrzeby w mojej tabeli stopionych danych:

Zastąp cały ciąg w dowolnym miejscu w dataframe na podstawie częściowego dopasowania za pomocą dplyr

Szukałem łatwego sposobu na zastąpienie całego ciągu w jednej z kolumn w tabeli danych częściowym pasującym ciągiem. Nie mogłem znaleźć prostego dopasowania na forum, stąd ten post.

dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3")
> dt
      x    y    z
1:  A_1  K_1  P_1
2: BB_2 LL_2 QQ_2
3: CC_3 MM_3 RR_3

zamień wiele wartości w col na ywiele wzorców do dopasowania:

dt[,2]<-str_replace_all(as.matrix(dt[,2]),c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR"))

użycie as.matrix()w kolumnie wyklucza ostrzeżenie na wejściu do str_replace_all()funkcji. Wynik to:

> dt[,2]<-str_replace_all(as.matrix(dt[,2]),c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR"))
> dt
      x       y    z
1:  A_1 FORMULA  P_1
2: BB_2    RACE QQ_2
3: CC_3     CAR RR_3
>

bardzo nieeleganckie, ale działało dla mnie, gdy dane w kolumnie są duże, wydawało się to szybkim rozwiązaniem.

Wymaga library(stringr). Wszelkie sugestie dotyczące ulepszeń są mile widziane.

Edytujesz ten post, ponieważ próbowałem czegoś jak poniżej:

dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3"))            
dt[, nu_col := c(1:3)]
molten.dt<-melt(dt,id.vars = "nu_col", measure.vars = c("x","y","z"))
molten.dt[, one_more := ifelse(grepl("A_.*", value), "HONDA","FERRARI")]

Błąd, który widzę na konsoli Rstudio to:

Error in `:=`(one_more, ifelse(grepl("A_.*", value), "HONDA", "FERRARI")) : 
  Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").

Działa doskonale na Terminalu R.

> dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_$
> dt[, nu_col := c(1:3)]
> molten.dt<-melt(dt,id.vars = "nu_col", measure.vars = c("x","y","z"))
> molten.dt
   nu_col variable value
1:      1        x   A_1
2:      2        x  BB_2
3:      3        x  CC_3
4:      1        y   K_1
5:      2        y  LL_2
6:      3        y  MM_3
7:      1        z   P_1
8:      2        z  QQ_2
9:      3        z  RR_3
> molten.dt[, one_more := ifelse(grepl("A_.*", value), "HONDA","FERRARI")]
> molten.dt
   nu_col variable value one_more
1:      1        x   A_1    HONDA
2:      2        x  BB_2  FERRARI
3:      3        x  CC_3  FERRARI
4:      1        y   K_1  FERRARI
5:      2        y  LL_2  FERRARI
6:      3        y  MM_3  FERRARI
7:      1        z   P_1  FERRARI
8:      2        z  QQ_2  FERRARI
9:      3        z  RR_3  FERRARI
>

Odpowiedzi

1 Cole Nov 23 2020 at 01:06

data.table ma inny interfejs API do aktualizacji. Chociaż byłoby to dplyr :

tib <- tib %>% mutate(new_col = old_col + 2)

To samo dzieje się na miejscu za pomocą :=operatora:

dt[, new_col := old_col + 2]

Zwróć więc uwagę, że kiedy już znajdziemy się w nawiasach, możemy przekazać wektor do innych funkcji. Aby zastosować to do twojego przykładu, możemy zrobić ...

library(data.table)
library(stringr)
dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3"))            

dt[, y := str_replace_all(y,c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR")) ]               

dt

##         x       y      z
##    <char>  <char> <char>
## 1:    A_1 FORMULA    P_1
## 2:   BB_2    RACE   QQ_2
## 3:   CC_3     CAR   RR_3

Uwaga, ponieważ str_replace_allspodziewa się wektor, mogłeś wymienić as.matrix(dt[,2])z dt[[2]]. Różnica polega na tym, że dt[, 2]tworzy jednokolumnowy data.table; as.matrix(dt[, 2])tworzy macierz jednokolumnową, a dt[[2]]produkuje wektor. Nadal zalecałbym używanie dt[, new := old + 2]typu składni.