arv*_*000 22 r data.table
我想将data.table cols的子集转换为新类.这里有一个流行的问题(在data.table中转换列类)但是答案创建了一个新对象,而不是在starter对象上运行.
举个例子:
dat <- data.frame(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10))
cols <- c('ID', 'Quarter')
Run Code Online (Sandbox Code Playgroud)
如何最好地将cols
列转换为(例如)一个因子?在普通的data.frame中,你可以这样做:
dat[, cols] <- lapply(dat[, cols], factor)
Run Code Online (Sandbox Code Playgroud)
但这对data.table不起作用,也不适用
dat[, .SD := lapply(.SD, factor), .SDcols = cols]
Run Code Online (Sandbox Code Playgroud)
来自Matt Dowle(2013年12月)的链接问题中的评论表明以下情况很好,但看起来不那么优雅.
for (j in cols) set(dat, j = j, value = factor(dat[[j]]))
Run Code Online (Sandbox Code Playgroud)
目前是否有更好的data.table答案(即更短+不生成计数器变量),或者我应该只使用上面的+ rm(j)
?
Jaa*_*aap 44
除了使用Matt Dowle建议的选项外,另一种更改列类的方法如下:
dat[, (cols) := lapply(.SD, factor), .SDcols = cols]
Run Code Online (Sandbox Code Playgroud)
通过使用:=
运算符,您可以通过引用更新数据表.检查一下是否有效:
> sapply(dat,class)
ID Quarter value
"factor" "factor" "numeric"
Run Code Online (Sandbox Code Playgroud)
正如@MattDowle在评论中所建议的那样,您还可以使用for(...) set(...)
如下组合:
for (col in cols) set(dat, j = col, value = factor(dat[[col]]))
Run Code Online (Sandbox Code Playgroud)
这将得到相同的结果.第三种选择是:
for (col in cols) dat[, (col) := factor(dat[[col]])]
Run Code Online (Sandbox Code Playgroud)
在较小的数据集上,该for(...) set(...)
选项比lapply
选项快三倍(但这并不重要,因为它是一个小数据集).在较大的数据集(例如,200万行)上,这些方法中的每一种花费大约相同的时间量.为了测试更大的数据集,我使用了:
dat <- data.table(ID=c(rep("A", 1e6), rep("B",1e6)),
Quarter=c(1:1e6, 1:1e6),
value=rnorm(10))
Run Code Online (Sandbox Code Playgroud)
有时,您必须以不同的方式执行此操作(例如,将数值存储为因子时).然后你必须使用这样的东西:
dat[, (cols) := lapply(.SD, function(x) as.integer(as.character(x))), .SDcols = cols]
Run Code Online (Sandbox Code Playgroud)
警告: 下面的解释是不是该data.table
做的事情的三通.数据表不是通过引用更新的,因为副本被创建并存储在内存中(如@Frank所指出的),这会增加内存使用量.它更多是为了解释工作的补充with = FALSE
.
如果要以与使用数据帧相同的方式更改列类,则必须with = FALSE
按如下方式添加:
dat[, cols] <- lapply(dat[, cols, with = FALSE], factor)
Run Code Online (Sandbox Code Playgroud)
检查一下是否有效:
> sapply(dat,class)
ID Quarter value
"factor" "factor" "numeric"
Run Code Online (Sandbox Code Playgroud)
如果不添加with = FALSE
,datatable将评估dat[, cols]
为向量.检查dat[, cols]
和之间的输出差异dat[, cols, with = FALSE]
:
> dat[, cols]
[1] "ID" "Quarter"
> dat[, cols, with = FALSE]
ID Quarter
1: A 1
2: A 2
3: A 3
4: A 4
5: A 5
6: B 1
7: B 2
8: B 3
9: B 4
10: B 5
Run Code Online (Sandbox Code Playgroud)