【发布时间】:2019-12-02 15:54:59
【问题描述】:
在一个新的用户创建函数中,我喜欢做一些 data.table 转换,特别是我喜欢使用 ':=' 命令创建一个新列。
假设我想创建一个名为 Sex 的新列,它在我的示例 data.frame df 中将 df$sex 列的第一个字母大写。
我的准备函数的输出应该是一个与以前同名但带有附加“大写”列的 data.table。
我尝试了几种方法来遍历 data.table。但是我总是收到以下警告(并且没有正确的输出):
警告信息: 在
[.data.table(x, ,:=(Sex, stringr::str_to_title(sex))) 中: 通过获取 data.table 的(浅)副本检测并修复无效的 .internal.selfref ,以便 := 可以通过引用添加此新列。在较早的时候,此 data.table 已由 R 复制(或使用 structure() 或类似方法手动创建)。避免 names
library(data.table)
library(magrittr)
library(stringr)
df <- data.frame("age" = c(17, 04),
sex = c("m", "f"))
df %>% setDT()
is.data.table(df)
这是编写我的函数的最简单方法:
prepare1<-function(x){
x[,Sex:=stringr::str_to_title(sex)]
}
prepare1(df)
#--> WARNING. (as block quoted above)
prepare2<-function(x){
x[, `:=`(Sex, stringr::str_to_title(sex))]
}
prepare2(df)
#--> WARNING. . (as block quoted above)
prepare3<-function(x){
require(data.table)
y <-as.data.table(list(x))
y <- y[,Sex:=stringr::str_to_title(sex)]
x <<- y
}
prepare3(df)
最后一个版本没有抛出警告,而是创建了一个名为 x 的新数据集。但我想覆盖我放在函数中的数据集(如果我必须这样做的话。)
从:= help file 我也知道我可以使用 set,但是我无法适当地调整命令。如果这可以解决我的问题,我也很乐意在这方面得到帮助! set(x, i = NULL, Sex, str_to_title(sex)) 显然是错误的......
根据要求/为了让 cmets 中的讨论更清楚,我展示了我的代码如何产生问题
library(data.table)
library(stringr)
df <- data.frame("age" = c(17, 04),
sex = c("m", "f"))
GetLastAssigned <- function(match = "<- *data.frame",
remove = " *<-.*") {
f <- tempfile()
savehistory(f)
history <- readLines(f)
unlink(f)
match <- grep(match, history, value = TRUE)
get(sub(remove, "", match[length(match)]))
}
#ok, no need for magrittr
setDT(GetLastAssigned())
#check the last function worked
is.data.table(df)
prepare1<-function(x){
x[,Sex:=stringr::str_to_title(sex)]
}
prepare1(GetLastAssigned())
# I get a warning and it does not work.
prepare1(df)
# I get a warning and it does not work, either.
#If I manually type setDT(df) everything works fine but I cannot type the "right" dfs at all the places where I need to do this transformation.
【问题讨论】:
-
罪魁祸首似乎是
magrittr。如果您只是执行setDT(df),这将按预期工作。 -
如果您查看
`%>%`的源代码,您会发现很多函数都可以很好地解决此类问题。 -
谢谢。但我需要 Magrittr,因为我在实际应用程序中不需要通过另一个函数设置 df。 IE。 “myotherfunction”返回 df。但它需要是 "myotherfunction %>% setDT() 或 setDT(myotherfunction)。
-
但是请点赞。这是一个写得很好的问题,有一个很好的可重复的例子。
-
@Roland 不确定是否是同一个问题,但我遇到了相关问题 github.com/Rdatatable/data.table/issues/1628 链接到 stackoverflow.com/a/26072152,其中 Arun 在 2014 年以“到目前为止的想法是使用 @987654333 @ 在将其提供给函数之前将其转换为 data.tables。但我希望解决这些情况"
标签: r data.table