R data.table使用任何
我正在处理一个数据集,这个数据集很大,有很多列。我正在使用data.table加速计算。但是,在某些情况下,我不确定如何将data.table转换回data.frame并进行计算。这会减慢进程。如果能就如何在data.table中编写下面的内容提出建议,将会有很大帮助。下面是我的代码在虚拟数据上的快照-R data.table使用任何,r,data.table,apply,lapply,any,R,Data.table,Apply,Lapply,Any,我正在处理一个数据集,这个数据集很大,有很多列。我正在使用data.table加速计算。但是,在某些情况下,我不确定如何将data.table转换回data.frame并进行计算。这会减慢进程。如果能就如何在data.table中编写下面的内容提出建议,将会有很大帮助。下面是我的代码在虚拟数据上的快照- library(data.table) #### set the seed value set.seed(9901) #### create the sample variables for
library(data.table)
#### set the seed value
set.seed(9901)
#### create the sample variables for creating the data
p01 <- sample(1:100,1000,replace = T)
p02 <- sample(1:100,1000,replace = T)
p03 <- sample(1:100,1000,replace = T)
p04 <- sample(1:100,1000,replace = T)
p05 <- sample(1:100,1000,replace = T)
p06 <- sample(1:100,1000,replace = T)
p07 <- sample(1:100,1000,replace = T)
#### create the data.table
data <- data.table(cbind(p01,p02,p03,p04,p05,p06,p07))
###user input for last column
lcol <- 6
###calculate start column as last - 3
scol <- lcol-3
###calculate average for scol:lcol
data <- data[,avg:= apply(.SD,1,mean,na.rm=T),.SDcols=scol:lcol]
###converting to data.frame since do not know the solution in data.table
data <- as.data.frame(data)
###calculate the trend in percentage
data$t01 <- data[,lcol-00]/data[,"avg"]-1
data$t02 <- data[,lcol-01]/data[,"avg"]-1
data$t03 <- data[,lcol-02]/data[,"avg"]-1
data$t04 <- data[,lcol-03]/data[,"avg"]-1
data$t05 <- data[,lcol-04]/data[,"avg"]-1
###converting back to data.table
data <- as.data.table(data)
###calculate the min and max for the trend
data1 <- data[,`:=` (trend_min = apply(.SD,1,min,na.rm=T),
trend_max = apply(.SD,1,max,na.rm=T)),.SDcols=c(scol:lcol)]
###calculate flag if any of t04 OR t05 is an outlier for min and max values. This would be many columns in actual data
data1$flag1 <- ifelse(data1$t04 < data1$trend_min | data1$t04 > data1$trend_max,1,0)
data1$flag2 <- ifelse(data1$t05 < data1$trend_min | data1$t05 > data1$trend_max,1,0)
data1$flag <- ifelse(data1$flag1 == 1 | data1$flag2 == 1,1,0)
库(data.table)
####设置种子值
种子集(9901)
####创建用于创建数据的示例变量
p01一些步骤可以变得更有效,即不使用apply
和MARGIN=1
,mean
,min
,max
可以替换为rowMeans
,pmin
,pmax
library(data.table)
data[ , avg:= rowMeans(.SD, na.rm = TRUE) ,.SDcols=scol:lcol]
data[, sprintf('t%02d', 1:5) := lapply(.SD, function(x) x/avg -1),
.SDcol = patterns("^p0[1-5]")]
data[,`:=` (trend_min = do.call(pmin, c(.SD,na.rm=TRUE)),
trend_max = do.call(pmax, c(.SD,na.rm=TRUE)) ),.SDcols=c(scol:lcol)]
data
# p01 p02 p03 p04 p05 p06 p07 avg t01 t02 t03 t04 t05 trend_min trend_max
# 1: 35 53 22 82 100 59 69 65.75 -0.46768061 -0.19391635 -0.6653992 0.24714829 0.5209125 22 100
# 2: 78 75 15 65 70 69 66 54.75 0.42465753 0.36986301 -0.7260274 0.18721461 0.2785388 15 70
# 3: 15 45 27 61 63 75 99 56.50 -0.73451327 -0.20353982 -0.5221239 0.07964602 0.1150442 27 75
# 4: 41 80 13 22 63 84 17 45.50 -0.09890110 0.75824176 -0.7142857 -0.51648352 0.3846154 13 84
# 5: 53 9 75 47 25 75 66 55.50 -0.04504505 -0.83783784 0.3513514 -0.15315315 -0.5495495 25 75
# ---
# 996: 33 75 9 61 74 55 57 49.75 -0.33668342 0.50753769 -0.8190955 0.22613065 0.4874372 9 74
# 997: 24 68 74 11 43 75 37 50.75 -0.52709360 0.33990148 0.4581281 -0.78325123 -0.1527094 11 75
# 998: 62 78 82 97 56 50 74 71.25 -0.12982456 0.09473684 0.1508772 0.36140351 -0.2140351 50 97
# 999: 70 88 93 4 39 75 93 52.75 0.32701422 0.66824645 0.7630332 -0.92417062 -0.2606635 4 93
#1000: 20 50 99 94 62 66 98 80.25 -0.75077882 -0.37694704 0.2336449 0.17133956 -0.2274143 62 99
然后创建“标志”
data[, flag := +(Reduce(`|`, lapply(.SD, function(x)
x < trend_min| x > trend_max))), .SDcols = t04:t05]
data[,flag:=+(Reduce(`|`),lapply(.SD,函数(x)
xtrend_max)),.SDcols=t04:t05]
I将apply(.SD,1,mean
更改为data[,aveg:=rowMeans(.SD,na.rm=TRUE),.SDcols=…]
和min/max
计算更改为do.call(pmin.SD)
和do.call(pmax.SD)
我认为这些步骤将大大增强您的efficiency@akrun,谢谢你的建议…我也必须计算SD,我没有得到类似rowSD的东西,所以为了保持一致,我使用了apply…使用RowsMeans有什么额外的好处吗?如果你将它从matrixStats
转换为matrix,就会有rowSD
根据你的ifelse代码,它是在同一个“t04”上执行的。这是一个打字错误。你是说t05吗?@akrun谢谢你指出它。更新了应该是的代码t05@user1412它只是将逻辑强制为二进制,即TRUE/FALSE
强制为1/0
,或者可以使用as.integer
完成。也许您需要映射(
/,.SD[,-1,with=FALSE],.SD[,-ncol(.SD),with=FALSE)
@user1412在这里,您要对4列进行除法。因此您需要数据[,sprintf('t%02d',1:4):=Map(
/,.SD[,-1,with=FALSE],.SD[,-ncol(.SD),with=FALSE]),.SDcol模式(^p0[1-5])
只需执行Map(函数(x,y))x/y-1、.SD[-1,with=FALSE]、.SD[,-ncol(.SD),with=FALSE])
非常感谢您……您让它变得如此简单……有很多东西要向您学习:)@user1412这里的-ncol
正在删除最后一列,-1
正在删除.SD
的第一列。它的长度是相同的