似乎有些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]“数据表”“数据框架”
class(mutate_if(dt, is.numeric, as.numeric))
[1]“数据框架”
但是,这种动作不会发生:
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,或者每次使用范围限定的mutate函数之一时都需要强制as.data.table吗?
答案 0 :(得分:1)
您的问题可能没有令人满意的答案,但是这些包装函数可以使您不必每次都转换回数据表。
如果您不想将它们包含在每个脚本或项目中,又不想将它们放入.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(...)
}
}
答案 1 :(得分:1)
如果您想尝试其他方法,
我最近发布了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
。
答案 2 :(得分:0)
您尝试过使用
df %>%
mutate_if(yourmutate) %>%
data.table()
您的框架将同时为data.table
和data.frame
。
按照您的示例:
require(dplyr)
require(data.table)
data("iris")
dt <- as.data.table(iris)
class(dt)
#
dt <- mutate_if(dt, is.numeric, as.numeric) %>% data.table()
class(dt)