什么可以替代R中的嵌套循环

什么可以替代R中的嵌套循环,r,nested-loops,lapply,R,Nested Loops,Lapply,我想通过运行给定两个变量x和y的多个场景,从R中的dataframeinput创建dataframeoutput。列output是列value中所有值的总和,其中xcol

我想通过运行给定两个变量
x
y
的多个场景,从R中的dataframe
input
创建dataframe
output
。列
output
是列
value
中所有值的总和,其中
xcol

input =
xcol ycol value
1   5   4
2   6   9
3   7   8
4   9   7
5   14  8

我的代码当前是这样的:

for (x in 2:6) {
  if (x%% 2){
    next
  }
  for (y in 5:15) {
    if (y %% 5){
      next
    }
    print(x)
    print(y)
    print(sum(input$value[!is.na(input$xcol) & !is.na(input$ycol) & !is.na(input$value) & 
              input$xcol < x &  input$ycol < y]))
  }
}
for(2:6中的x){
如果(x%%2){
下一个
}
对于(5:15中的y){
如果(y%%5){
下一个
}
打印(x)
打印(y)
打印(总和(输入$value[!is.na(输入$xcol)&!is.na(输入$ycol)&!is.na(输入$value)&)
输入$xcol
我认为应该有更好的方法使用lappy&sapply替换这个嵌套循环,并创建一个数据帧。我非常感谢你的帮助


谢谢

这不是最优雅的解决方案,但您可以用lappy替换for循环:

lapply (2:6, function(x) {
  if (x%% 2){
    next
  }
  lapply (5:15, function(y) {
    if (y %% 5){
      next
    }
    print(x)
    print(y)
    print(sum(input$value[!is.na(input$xcol) & !is.na(input$ycol) & !is.na(input$value) & 
              input$xcol < x &  input$ycol < y]))
  })
})
lappy(2:6,函数(x){
如果(x%%2){
下一个
}
lappy(5:15,函数(y){
如果(y%%5){
下一个
}
打印(x)
打印(y)
打印(总和(输入$value[!is.na(输入$xcol)&!is.na(输入$ycol)&!is.na(输入$value)&)
输入$xcol
从某种意义上讲,这更像是一个实验设计,在这个设计中,您迭代了不同的
x
y
的可能值

input =
xcol ycol value
1   5   4
2   6   9
3   7   8
4   9   7
5   14  8
xs <- 2:6
ys <- 5:15
eg <- expand.grid(x = xs, y = ys)
head(eg)
#   x y
# 1 2 5
# 2 3 5
# 3 4 5
# 4 5 5
# 5 6 5
# 6 2 6
从这里开始,您可以迭代行:

eg$out <- sapply(seq_len(nrow(eg)), function(r) {
  sum(input$value[ complete.cases(input) & input$xcol < eg$x[r] & input$ycol < eg$y[r] ])
})
eg
#   x  y out
# 1 2  5   0
# 2 4  5   0
# 3 6  5   0
# 4 2 10   4
# 5 4 10  21
# 6 6 10  28
# 7 2 15   4
# 8 4 15  21
# 9 6 15  36
自从“code golf”之后,我使用了第一个,但是如果实际的
输入
data.frame包含其他列,那么您可能更希望第二个列能够选择哪些列需要非
NA

  • expand.grid
    非常适合这种类型的扩展。但是,如果您查看的数据集要大得多(包括您的筛选比
    %%
    提供的数据集更复杂),那么它可能会有点昂贵,因为它必须在内存中创建整个
    data.frame
    。Python使用惰性迭代器在这里很有用,在这种情况下,您可能更喜欢使用(github gist中的扩展函数和一些文档:)

  • eg$out <- sapply(seq_len(nrow(eg)), function(r) {
      sum(input$value[ complete.cases(input) & input$xcol < eg$x[r] & input$ycol < eg$y[r] ])
    })
    eg
    #   x  y out
    # 1 2  5   0
    # 2 4  5   0
    # 3 6  5   0
    # 4 2 10   4
    # 5 4 10  21
    # 6 6 10  28
    # 7 2 15   4
    # 8 4 15  21
    # 9 6 15  36
    
    complete.cases(input)                                         # 1
    complete.cases(input[c("xcol","ycol","value")])               # 2
    !is.na(input$xcol) & !is.na(input$xcol) & !is.na(input$value) # 3