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