mutate_if, Summarize_at и т. д. приведение data.table к data.frame - PullRequest
2 голосов
/ 15 мая 2019

Кажется, что некоторые функции dplyr, включая mutate_if, mutate_all, mutate_at и т. Д., Принудительно вводят data.table в data.frame. Это кажется странным поведением, даже если оно задокументировано в? Mutate_all (в разделе «Значение» указано «data.frame» - но оно не приводит к переходу на data.frames.)

require(dplyr)
require(data.table)
data("iris")
dt <- as.data.table(iris)
class(dt)

[1] "data.table" "data.frame"

class(mutate_if(dt, is.numeric, as.numeric))

[1] "data.frame"

Однако с тибблами этого не происходит:

tb <- as_tibble(iris)
class(tb)

[1] "tbl_df" "tbl" "data.frame"

class(mutate_if(tb, is.numeric, as.numeric))

[1] "tbl_df" "tbl" "data.frame"

Есть ли какой-нибудь способ сохранить data.table или мне нужно принудительно вызывать as.data.table каждый раз, когда я использую одну из функций видимости с измененной областью действия?

Ответы [ 2 ]

2 голосов
/ 08 июня 2019

Если вы хотите попробовать альтернативу, я недавно выпустил пакет table.express, который использует множество dplyr и пользовательских глаголов для построения data.table выражений.

Теперь, когда table.express v0.2.0 отсутствует, больше dplyr глаголов могут быть сопоставлены с пользовательскими, но есть некоторые предостережения (проверьте связанную виньетку).Некоторые примеры:

library(data.table)
library(table.express)

data("iris")
DT <- as.data.table(iris)

# mutate_all (modification by reference does not print)
DT %>%
  start_expr %>%
  mutate_sd(everything(), as.integer) %>%
  end_expr

# mutate_if
DT %>%
  start_expr %>%
  mutate_sd(is.numeric(.COL), as.integer) %>%
  end_expr

# mutate_at
DT %>%
  start_expr %>%
  mutate_sd(contains("."), .COL * 1.5) %>%
  end_expr

# transmute_all
DT %>%
  start_expr %>%
  transmute_sd(everything(), as.integer) %>%
  end_expr

# transmute_if
DT %>%
  start_expr %>%
  transmute_sd(is.numeric(.COL), as.integer) %>%
  end_expr

# transmute_at
DT %>%
  start_expr %>%
  transmute_sd(contains("."), as.integer) %>%
  end_expr

Обратите внимание, что mutate_sd по умолчанию изменяется по ссылке, поэтому, если хотите, переопределите DT между примерами.

1 голос
/ 15 мая 2019

Может не быть удовлетворительного ответа на ваш вопрос, но эти функции-обёртки сделают его таким, что вам не придется каждый раз возвращаться к таблице данных.

Иесли вы не хотите включать их в каждый сценарий или проект и не хотите помещать их в .Rprofile, вы можете даже сделать из них крошечный пакет.Это на удивление легко.

mutate_all <- function(.tbl, ...) {
  if ("data.table" %in% class(.tbl)) {
    .tbl %>% mutate_all(...) %>% as.data.table()
  } else {
    .tbl %>% mutate_all(...)
  }
}
mutate_if <- function(.tbl, ...) {
  if ("data.table" %in% class(.tbl)) {
    .tbl %>% mutate_if(...) %>% as.data.table()
  } else {
    .tbl %>% mutate_if(...)
  }
}
mutate_at <- function(.tbl, ...) {
  if ("data.table" %in% class(.tbl)) {
    .tbl %>% mutate_at(...) %>% as.data.table()
  } else {
    .tbl %>% mutate_at(...)
  }
}
transmute_all <- function(.tbl, ...) {
  if ("data.table" %in% class(.tbl)) {
    .tbl %>% transmute_all(...) %>% as.data.table()
  } else {
    .tbl %>% transmute_all(...)
  }
}
transmute_if <- function(.tbl, ...) {
  if ("data.table" %in% class(.tbl)) {
    .tbl %>% transmute_if(...) %>% as.data.table()
  } else {
    .tbl %>% transmute_if(...)
  }
}
transmute_at <- function(.tbl, ...) {
  if ("data.table" %in% class(.tbl)) {
    .tbl %>% transmute_at(...) %>% as.data.table()
  } else {
    .tbl %>% transmute_at(...)
  }
}
...