我知道还有更多这样的问题。但是,我无法完成它。 我有一个非常大的data.table,大约有800.000行。每行包含一些特定数据,然后是一些需求数据2年(从第12列开始),最后一列是一个数字。此数字确定应替换的需求列数。
一行示例:
ITEM COUNTRY Q1 Q2 Q3 Q4 ---- Q24 NUMBER
1 1 0 0 0 0 ---- 2 2
例如,如果这是一个名为x
的向量,我会这样做:
x[2:(2+x$NUMBER-1)] <- NA
现在我想对所有行执行此操作。 for循环太慢了。所以我在考虑申请。
fun_NA <- function(x){ #x is then a row of the data.table
#still use that with x[,] as x is still a data.table and not a vector
if(x[,60]>0){
x[,12:(12+as.numeric(x[,60])-1)] <- NA
}
}
dt = apply(dt, 1, fun_NA)
其中dt
是我的data.table,有60列。第一个需求值从第12列开始。它不起作用..现在它在x [,60]中给出了错误&#34;错误:维数不正确&#34;,但我也尝试了其他方法并收到其他错误。
我想要这样做的原因: 该数字表示该项目能够销售的月份(在我的数据集的第一个月之后),因此在之前的几个月中,需求不是0,但是根本不存在。我需要它是NA,因为0将在以后导致错误的计算。
编辑: 删除了逗号,这是新代码,
fun_NA <- function(x){ #x is then a row of the data.table
if(x[60]>0){
x[12:(12+as.numeric(x[60])-1)] <- NA
}
}
dt = apply(dt, 1, fun_NA)
但是,这会返回一个包含所有NULL和NA元素的大型列表。
编辑:数据表的头部如下:( dput)
structure(list(ITEM = c(1, 1, 2, 2, 2, 2), COUNTRY = c(1, 2,
3, 4, 5, 2), DATE = c("2015-02-02", "2015-02-02", "2014-09-27",
"2014-09-27", "2014-09-27", "2014-09-27"), q_1 = c(0, 0, 2, 0,
0, 133), q_2 = c(0, 0, 24, 0, 9, 119), q_3 = c(0, 0, 15, 0, 13,
121), q_4 = c(0, 0, 7, 0, 2, 51), q_5 = c(0, 0, 12, 0, 6, 59),
q_6 = c(0, 0, 3, 0, 0, 36), q_7 = c(0, 0, 6, 0, 6, 41), q_8 = c(0,
0, 19, 0, 4, 42), q_9 = c(0, 0, 3, 0, 5, 48), q_10 = c(0,
0, 5, 0, 11, 49), q_11 = c(0, 0, 6, 0, 1, 42), q_12 = c(0,
0, 0, 0, 8, 70), q_13 = c(0, 0, 1, 0, 19, 81), q_14 = c(0,
0, 5, 0, 98, 86), q_15 = c(0, 0, 12, 0, 10, 152), q_16 = c(0,
0, 7, 0, 8, 95), q_17 = c(0, 0, 30, 0, 5, 62), q_18 = c(0,
0, 6, 0, 10, 47), q_19 = c(0, 0, 7, 0, 1, 35), q_20 = c(2,
0, 7, 0, 0, 47), q_21 = c(0, 2, 16, 5, 4, 70), q_22 = c(0,
0, 7, 0, 7, 46), q_23 = c(0, 0, 8, 0, 79, 20), q_24 = c(0,
0, 5, 0, 26, 45), NUMBER = c(13, 13, 8, 8, 8, 8)), .Names = c("ITEM",
"COUNTRY", "DATE", "q_1", "q_2", "q_3", "q_4", "q_5", "q_6",
"q_7", "q_8", "q_9", "q_10", "q_11", "q_12", "q_13", "q_14",
"q_15", "q_16", "q_17", "q_18", "q_19", "q_20", "q_21", "q_22",
"q_23", "q_24", "NUMBER"), class = c("data.table", "data.frame"
), row.names = c(NA, -6L), .internal.selfref = <pointer: 0x0000000004490788>)
答案 0 :(得分:1)
通常,按列工作更有效。
lapply(1:24, function(i) dt[i <= NUMBER, (paste0("q_", i)) := NA])
ITEM COUNTRY DATE q_1 q_2 q_3 q_4 q_5 q_6 q_7 q_8 q_9 q_10 q_11 q_12 q_13 q_14 q_15 q_16 q_17 q_18 q_19 q_20 1: 1 1 2015-02-02 NA NA NA NA NA NA NA NA NA NA NA NA NA 0 0 0 0 0 0 2 2: 1 2 2015-02-02 NA NA NA NA NA NA NA NA NA NA NA NA NA 0 0 0 0 0 0 0 3: 2 3 2014-09-27 NA NA NA NA NA NA NA NA 3 5 6 0 1 5 12 7 30 6 7 7 4: 2 4 2014-09-27 NA NA NA NA NA NA NA NA 0 0 0 0 0 0 0 0 0 0 0 0 5: 2 5 2014-09-27 NA NA NA NA NA NA NA NA 5 11 1 8 19 98 10 8 5 10 1 0 6: 2 2 2014-09-27 NA NA NA NA NA NA NA NA 48 49 42 70 81 86 152 95 62 47 35 47 q_21 q_22 q_23 q_24 NUMBER 1: 0 0 0 0 13 2: 2 0 0 0 13 3: 16 7 8 5 8 4: 5 0 0 0 8 5: 4 7 79 26 8 6: 70 46 20 45 8
我们遍历所有24列。对于每一行,测试当前列中的值是否需要根据其列号替换为NA。这些值会在适当的位置更新,从而节省时间和内存。
我已经使用100万行的样本数据集测试了该解决方案,花费的时间不到0.2秒。
答案 1 :(得分:0)
由于你对函数的输入是一个向量,你应该删除所有的逗号,因为它只有一个维度。
fun_NA <- function(x){ #x is then a row of the data.table
#still use that with x[,] as x is still a data.table and not a vector
if(x[60]>0){
x[12:(12+as.numeric(x[60])-1)] <- NA
}
}
dt = apply(dt, 1, fun_NA)