【问题标题】:eliminate loop from rowwise subseting of data从数据的逐行子集中消除循环
【发布时间】:2016-07-01 08:32:04
【问题描述】:

我有两个数据集 - TEST end TRAIN。 TEST 是 TRAIN 的一个子集。通过使用列“prod”和“clnt”,我需要在 TRAIN 中找到与 TEST 对应的所有行(它是一对多对应)。然后我对TEST的“order”列的各个值进行时间分析(第一列“week”是时间)。

所以我取 TRAIN 的第一行,比较 TEST 的所有行是否其中一些包含相同的“prod”和“clnt”数字组合,并在 TS 中记录“order”各自的值。通常我在每行 TRAIN 的 TS 中有 0 到 10 个值。然后我对 TS 进行一些计算(在这个人为的情况下,只是平均值(TS))并记录结果以及数据集 Subm 中 TEST 行的“Id”。

该算法有效,但因为我在 TRAIN 和 TEST 中有数百万行,所以我需要它尽可能快,尤其是要摆脱循环,这是最慢的部分。可能我也搞砸了 data.frame 声明/使用,但我不确定。

set.seed(42)
NumObsTrain=100000 # this can be as much as 70 000 000
NumObsTest=10000 # this can be as much as 6 000 000

#create the TRAIN data set
train1=floor(runif(NumObsTrain, min=0, max=NumObsTrain+1))
train1=matrix(train1,ncol = 2)
train=cbind(8,train1) #week
train=rbind(train,cbind(9,train1)) #week
train=cbind(train,runif(NumObsTrain,min=1,max=10)) #order
train=cbind(c(1:nrow(train)),train)# id number of each row
colnames(train)=c("id","week","prod","clnt","order")
train=as.data.frame(train)
train=train[sample(nrow(train)),] # reflush the rows of train

# Create the TEST dataset
test=train[1:NumObsTest,]
test[,"week"][1:{NumObsTest/2}]=10
test[,"week"][{(NumObsTest/2)+1}:NumObsTest]=11

TS=numeric(length = 10)
id=c(1:NumObsTest*2)
order=c(1:NumObsTest*2)
Subm=data.frame(id,order)
ptm <- proc.time()

# This is the loop
for (i in 1:NumObsTest){
   Subm$id[i]=test$id[i]
   TS=train$order[train$clnt==test$clnt[i]&train$prod==test$prod[i]]
   Subm$order[i]=mean(TS)
}
proc.time() - ptm

【问题讨论】:

  • 你的解释有点不清楚。我运行了你的代码,但我不确定我应该看什么。为什么TS最后只有两个值? (至少在我尝试过时)从一开始的描述来看,您似乎想要所有 TRAIN 行也出现在 TEST 中,只考虑 prodclnt 列。如果是这种情况,使用dplyr::semi_join(train, test, by = c("prod", "clnt")) 将为您提供那部分答案。
  • @LuisUsie,这是人为的例子,它按预期工作。 TS 中只有两个值是正常的。你是对的,我想要所有的 TRAIN 行,出现在 TEST 中,缺点。 "prod" 和 "clnt" 唯一的问题是最后使用循环导致的低速。我知道一些向量化是必要的,但我还是 R 的新手。所以我会尝试关于 dplyr 的建议。
  • @sebastianmm 我试图提供工作示例。如果您只是运行脚本,它会生成所有必要的数据。
  • @LuisUsier 是的,现在它部分达到了目的。现在我需要从dlpyr 操作的结果中提取相等的行(考虑相等的偶数"prod"&amp;"clnt"),并对最后一列做一些数学运算,例如mean("order")。在这个(人工)示例中,我们每行有两次重复。在一般情况下,我不知道重复次数是多少 - 它们在各行之间是不同的,介于 0 到 10 之间。

标签: r for-loop subset vectorization


【解决方案1】:

下面将创建一个包含所有(prod, clnt)order 组合的data.frame,然后将它们按prodclnt 分组,然后取每个组的顺序的平均值。最终结果缺少id,由于某种原因,您的最终data.frame 中有更多数据,我不知道为什么。但是order 的结果是正确的。

newtrain <- train[, 3:5]
newtest <- test[, c(1, 3:4)]
x <- dplyr::inner_join(newtest, newtrain)
y <- dplyr::group_by(x, prod, clnt)
z <- dplyr::summarise(y, mean(order))

【讨论】:

    猜你喜欢
    • 2020-12-17
    • 1970-01-01
    • 2018-11-25
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    相关资源
    最近更新 更多