我知道如何对一个变量进行操作。我们可以使用均等()或cut()的组合。任何人都知道同时对100列执行此操作的汇总功能?
我知道我可以编写一个循环,但是很慢。有更快的方法吗?因为我正在研究一个大数据问题,并且也欢迎使用Revolution R的解决方案。谢谢进步!
澄清:我试图将每个列不仅在第一列中将每个列划分为20个范围。我不是试图将数据集分开,而是试图将变量转换为不同的范围。希望它能澄清。非常感谢
使用cut2()中的g参数选择将变量切入的断裂。
require(data.table)
require(Hmisc)
set.seed(123)
DT <- data.table(x1 = rnorm(10e5, 50, 50),
x2 = rnorm(10e5, 30, 50),
x3 = rnorm(10e5, 20, 50),
x4 = rnorm(10e5, 10, 50),
x5 = rnorm(10e5, 10, 50)
)
cut_qt <- DT[,sapply(.SD, function(x) if(is.numeric(x)) cut2(x, g = 4)), ]
print(cut_qt)
head(cut_qt)
x1 x2 x3 x4 x5
[1,] "[ 16.3, 50.0)" "[-199.6, -3.8)" "[ -13.7, 20.0)" "[ -23.8, 10.0)" "[ -23.74, 9.97)"
[2,] "[ 16.3, 50.0)" "[ 63.6,257.4]" "[ 20.0, 53.7)" "[-218.7,-23.8)" "[-222.34,-23.74)"
[3,] "[ 83.7,292.5]" "[ -3.8, 29.9)" "[ -13.7, 20.0)" "[ 43.7,247.6]" "[ -23.74, 9.97)"
[4,] "[ 50.0, 83.7)" "[ 63.6,257.4]" "[ -13.7, 20.0)" "[ 10.0, 43.7)" "[-222.34,-23.74)"
[5,] "[ 50.0, 83.7)" "[ 29.9, 63.6)" "[-232.5,-13.7)" "[ 10.0, 43.7)" "[-222.34,-23.74)"
[6,] "[ 83.7,292.5]" "[ 29.9, 63.6)" "[-232.5,-13.7)" "[ 43.7,247.6]" "[ -23.74, 9.97)"
考虑到OP正在处理一个大数据集,因为这很慢:
> system.time(DT[,lapply(.SD, function(x) if(is.numeric(x)) cut2(x, g = 4)), ])
user system elapsed
37.66 0.00 38.70
使用set()
的替代方法# 1) Calculate Quantiles
q <- DT[,sapply(.SD, function(x) if(is.numeric(x)) quantile(x)), ]
q
x1 x2 x3 x4 x5
0% -189.95953 -199.574605 -232.54139 -218.74362 -222.343247
25% 16.28067 -3.797748 -13.72424 -23.76578 -23.736187
50% 49.98701 29.938932 20.01473 10.03740 9.967671
75% 83.66663 63.614604 53.74529 43.73047 43.676887
100% 292.53835 257.368361 280.64704 247.64500 277.418083
# 2) Modify the existing DT with the categorical variables using set
cols_to_fix <- names(DT)
for (j in 1:length(cols_to_fix)){
column <- cols_to_fix[j]
brk = q[,j]
val = cut2(DT[[column]], cuts = brk)
set(DT, i=NULL, j=j, value = val)
}
system.time(for (j in 1:length(cols_to_fix)){
column <- cols_to_fix[j]
brk = q[,j]
val = cut2(DT[[column]], cuts = brk)
set(DT, i=NULL, j=j, value = val)
}
)
user system elapsed
4.71 0.00 4.83
新版本:
制作20列,100行数据框架:
df <- as.data.frame(replicate(20, sample(1:100)))
将每列用该列的十分路由分开;这会产生尺寸的2D列表10 x 20:
pieces <- vapply(df, function(x) split(x, cut(x, quantile(x, (0:10)/10))), vector("list", 10))
您可以使用矩阵符号访问内容
pieces[[2, 1]]
# [1] 20 12 14 16 11 19 17 13 18 15
您使用的是revolution-r
标签,因此我假设您正在运行RevolutionR。如果您的数据以Revolution XDF格式使用,则可以使用RevoEnhancements软件包使用RxDiscretize。它立即为数据集中的所有变量创建BINNING,并产生一个对象,您可以将其用作RXDATASTEP函数中的转换。从帮助页面:
library(RevoEnhancements)
# Equal Freq
discTransforms <- rxDiscretize(~ cost,
data = claimsXdf,
type = "freq",
nBins = 1000,
subscript = "disc",
sep = "_")
x <- rxDataStep(inData = claimsXdf, transforms = discTransforms)