The ultimate R data.table cheat sheet

Read in CSV file Import mydt <- fread(“myfile.csv”) myt <- read_csv(“myfile.csv”) #OR
myt <- vroom::vroom(“myfile.csv”) Import the first x number of rows of a CSV file Import mydt_x <- fread(“myfile.csv”, nrows = x) myt_x <- read_csv(“myfile.csv”, n_max = x) Import only those rows from a CSV file that match a certain pattern Import mydt_pattern <- fread(“grep ‘mypattern’ myfile.csv”) myt_pattern <- vroom::vroom(pipe(“grep ‘mypattern’ myfile.csv”)) Import a .gz compressed file Import mydt <- fread(“myfile.gz”) myt <- vroom::vroom(“myfile.gz”) Import a.zip compressed file import mydt <- fread(cmd = ‘unzip -cq myfile.zip’) myt <- read_csv(“myfile.zip”) Create data table from existing data frame (tibble for tidyverse) Import mydt <- as.data.table(mydf) #OR
setDT(mydf) myt <- as_tibble(mydf) Alter data.table in place without making a copy Wrangle any function that starts with set such as setkey(mydt, mycol) or using the := operator within brackets not applicable Order rows based on multiple column values Wrangle mydt2 <- mydt[order(colA, -colB)] #OR
setorder(mydt, colA, -colB) myt <- arrange(myt, colA, -colB) Rename columns Wrangle setnames(mydt, old = c(‘colA’,’colB’), new = c(‘NewColA’, ‘NewColB’)) myt <- rename(myt, NewColA = colA, NewColB = colB) Reordering columns: Move some columns to the front (left-most) position Wrangle setcolorder(mydt, c(“colB”, “colC”)) # colB now in position 1 and colC in position 2 myt <- relocate(myt, colB, colC) Filter rows for row number n Subset mydt2 <- mydt[n] myt2 <- slice(myt, n) Filter for the last row Subset mydt2 <- mydt[.N] myt2 <- slice(myt, n()) Filter rows by condition Subset # In some cases setkey(mydt, colA, colB) will speed performance
# for logical tests on colA and colB; same with other columns
mydt2 <- mydt[logical expression] myt2 <- filter(myt, logical expression) Filter rows where colA equals string1 or string2 Subset mydt2 <- mydt[colA %chin% c(“string1”, “string2”)] myt2 <- filter(myt, colA %in% c(“string1”, “string2”)) Filter rows where colA matches a regular expression Subset mydt2 <- mydt[colA %like% “mypattern”] myt2 <- filter(myt, stringr::str_detect(colA, “mypattern”)) Filter rows where colA values are between 2 numbers Subset mydt2 <- mydt[colA %between% c(n1, n2)] myt2 <- filter(myt, between(colA, n1, n2)) Filter for first n rows by group Subset mydt2 <- mydt[, .SD[1:n], by = groupcol] myt2 <- myt %>%
group_by(groupcol) %>%
slice(1:n) Filter rows for maximum value by group Subset mydt2 <- mydt[, .SD[which.max(valcol)], by = groupcol] myt2 <- myt %>%
group_by(groupcol) %>%
filter(valcol == max(valcol)) Select column and return results as a vector Subset myvec <- mydt[, colname] myvec <- pull(myt, colname) Select multiple columns to create a new data.table (data frame or tibble for tidyverse) Subset mydt2 <- mydt[, list(colA, colB)] #OR

mydt2 <- mydt[, .(colA, colB)] #OR

mydt2 <- mydt[, c(“colA”, “colB”)]

myt2 <- select(myt, colA, colB) Select multiple columns using a variable containing the column names Subset my_col_names <- c(“colA”, “colB”)
mydt2 <- mydt[, ..my_col_names] #OR

mydt2 <- mydt[, my_col_names, with = FALSE]

my_col_names <- c(“colA”, “colB”)
myt2 <- select(myt, all_of(my_col_names)) Select multiple columns and rename some Subset mydt2 <- mydt[, .(newname1 = col1, newname2 = col2, col3)] myt2 <- select(myt, newname1 = col1, newname2 = col2, col3) Exclude multiple columns Subset mydt2 <- mydt[, -c(“colA”, “colB”)] #OR

mydt2 <- mydt[, !c(“colA”, “colB”)] #OR

my_col_names <- c(“colA”, “colB”)
mydt2 <- mydt[, !..my_col_names]

myt2 <- select(myt, -c(colA, colB)) #OR
my_col_names <- c(“colA”, “colB”)
myt2 <- select(myt, -{{my_col_names}}) Remove duplicate rows based on values in multiple columns Subset mydt2 <- unique(mydt, by = c(“colA”, “colB”)) myt2 <- distinct(myt, colA, colB, .keep_all = TRUE) Count unique rows based on multiple columns Summarize uniqueN(mydt, by = c(“colA”, “colB”)) nrow(distinct(myt, colA, colB)) Run summary calculations on data Summarize mydt2 <- mydt[, myfun(colA …)] myt2 <- myt %>%
summarise(
ColName = myfun(colA …)
) Run summary calculations on data by one group Summarize mydt2 <- mydt[, myfun(colA …), by = groupcol] myt2 <- myt %>%
group_by(groupcol) %>%
summarise(
NewCol = myfun(colA…)
) Run summary calculations on data by one group and name new column Summarize mydt2 <- mydt[, .(MyNewCol = myfun(colA…)), by = groupcol] myt2 <- myt %>%
group_by(groupcol) %>%
summarise(
NewCol = myfun(colA…)
) Run summary calculations on data by multiple groups Summarize mydt2 <- mydt[, myfun(colA …), by = .(groupcol1, groupcol2)] myt2 <- myt %>%
group_by(groupcol1, groupcol2) %>%
summarise(
NewCol = myfun(colA…)
) Run summary calculation on filtered data by multiple groups Summarize mydt2 <- mydt[filter expression, myfun(colA), by = .(groupcol1, groupcol2)] myt2 <- myt %>%
filter(filter expression) %>%
group_by(groupcol1, groupcol2) %>%
summarise(
NewCol = myfun(colA), .groups = “keep”
) Count number of rows by groups Summarize mydt2 <- mydt[,.N, by = groupcol] #for one group #OR

mydt2 <- mydt[, .N, by = .(groupcol1, groupcol2)]

myt2 <- count(myt, groupcol) #for one group #OR
myt2 <- count(myt, groupcol1, groupcol2) Summarize multiple columns and return results in multiple columns Summarize mydt2 <- mydt[, lapply(.SD, myfun),
.SDcols = c(“colA”, “colB”)] myt2 <- myt %>%
summarise(
across(c(colA, colB), myfun)
) Summarize multiple columns by group and return results in multiple columns Summarize mydt2 <- mydt[, lapply(.SD, myfun),
.SDcols = c(“colA”, “colB”), by = groupcol] myt2 <- myt %>%
group_by(groupcol) %>%
summarise( across(c(colA, colB), myfun) ) Add a column Calculate mydt[, MyNewCol := myfun(colA)] myt <- myt %>%
mutate(
MyNewCol = myfun(colA)
) Add multiple columns at once Calculate # use any function or expression
mydt[, `:=`(NewCol1 = myfun(colA),
NewCol2 = colB + colC )] #OR

mydt[, c(“NewCol1”, “newCol2”) := list(myfun(colA), colB + colC)]

myt <- myt %>%
mutate(
MyNewCol1 = myfun(colA),
MyNewCol2 = colB + colC
) Add column using current and previous values from another column, such as finding the difference between value on a date vs. the prior date Calculate mydt[, Diff := colA – shift(colA)] myt <- mutate(myt, Diff = colA – lag(colA)) Add column referencing previous value of a column by a group Calculate mydt2 <- mydt[, Diff := colA – shift(colA), by = groupcol] myt2 <- myt %>%
group_by(groupcol) %>%
mutate(
Diff = colA – lag(colA)
) Add column with row ID numbers by group Calculate mydt[, myid := 1:.N, by = groupcol] myt <- myt %>%
group_by(groupcol) %>%
mutate(
myid = row_number()
) Add column based on several conditions without using multiple if else statements (like SQL’s CASE) Calculate # Needs data.table version 1.13 or later
# I like each condition on a new line but that’s not required
mydt2 <- mydt[, NewCol := fcase(
condition1, “Value1”,
condition2, “Value2”,
condition3, “Value3”,
default = “Other” # value for all else
)] myt2 <- myt %>%
mutate(
NewCol = case_when(
condition1 ~ “Value1”,
condition2 ~ “Value2”,
condition3 ~ “Value3”,
TRUE ~ “Other”
)
) Add column via operating by row Calculate mydt[, newcol := myfun(colB, colC, colD), by = 1:nrow(mydt)]
# or if colA has all unique values
mydt[, newcol := myfun(colB, colC, colD), by = colA] myt <- myt %>%
rowwise() %>%
mutate(
newcol = myfun(colB, colC, colD)
)
# or
myt <- myt %>%
rowwise() %>%
mutate(
#use dplyr select syntax:
newcol = myfun(c_across(colB:colD))
) Join two data sets by more than one column; keep all in set1 but only matches in set2 Join mydt <- dt2[dt1, on = c(“dt2col” = “dt1col”)] #OR
mydt <- merge(dt1, dt2, by.x = “dt1col”, by.y = “dt2col”, all.x = TRUE) #OR
setkey(dt1, “dt1col”)
setkey(dt2, “dt2col”)
mydt <- dt2[dt1] myt <- left_join(df1, df2, by = c(“df1col” = “df2col”)) Join 2 data sets by more than one column – keep all in set1 but only matches in set2 Join mydt <- merge(dt1, dt2, by.x = c(“dt1colA”, “dt1colB”), by.y = c(“dt2colA”, “dt2colB”), all.x = TRUE, all.y = FALSE) #OR

setkey(dt1, dt1colA, dt1colB)
setkey(dt2, dt2colA, dt2colB)
mydt <- dt2[dt1]

myt <- left_join(df1, df2, by = c(“df1colA” = “df2colA”, “df1colB” = “df2colB”)) Join two data sets by one common column; only keep matches Join mydt <- merge(dt1, dt2, by.x = “dtcol1”, by.y = “dtcol2”) myt <- inner_join(df1, df2, by = c(“df1col” = “df2col”)) Join two data sets by one common column and keep all data in both sets, whether or not there are matches Join mydt <- merge(dt1, dt2, by.x = “dtcol1”, by.y = “dtcol2”, all = TRUE) myt <- full_join(df1, df2, by = c(“df1col” = “df2col”)) Combine two data sets by adding rows from one to the bottom of another Join mydt_joined <- rbindlist(list(mydt, mydt2)) myt_joined <- bind_rows(myt, myt2) Reshape data wide to long Reshape mydt_long <- melt(mydt, measure.vars = c(“col1”, “col2”, “col3”), variable.name = “NewCategoryColName”, value.name = “NewValueColName”) myt_long <- pivot_longer(myt, cols = starts_with(“col”), names_to = “NewCategoryColName”, values_to = “NewValueColName”) Reshape data long to wide Reshape mydt_wide <- dcast(mydt, id_col1 ~ col1 , value.var = “ValueColName”) myt_wide <- pivot_wider(myt, names_from = col1, values_from =ValueColName) Chain multiple expressions Wrangle mydt[expr1][expr2] myt <- myt %>%
expr1 %>%
expr2 Export data to a CSV file Export fwrite(mydt, “myfile.csv”) write_csv(myt, “myfile.csv”) Append rows to an existing CSV file Export fwrite(mydt2, “myfile.csv”, append = TRUE) vroom::vroom_write(myt2, “myfile.csv”, delim = “,”, append = TRUE) Export data to a compressed CSV file Export fwrite(mydt, “myfile.csv.gz”, compress = “gzip”) vroom::vroom_write(myt, “myfile2.csv.gz”)

Source link