我想通过运行给定两个变量output
和input
的多个方案,从R中的数据框x
创建数据框y
。列output
是value
列xcol < x & ycol < y
中所有值的总和。
input =
xcol ycol value
1 5 4
2 6 9
3 7 8
4 9 7
5 14 8
和
output=
x y results
2 5 0
2 10 4
2 15 35
...
6 5 0
6 10 27
6 15 35
我的代码目前是这样的:
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]))
}
}
应该有一种更好的方法来使用lapply&amp;更换这个嵌套循环。我想,应该创造一个数据帧。我很感激任何帮助。
由于
答案 0 :(得分:1)
在某种意义上,这似乎更像是一个实验设计,您可以迭代x
和y
的不同可能值。
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
我认为您的%%
过滤应该在此之前/之前完成,所以:
xs <- xs[!xs %% 2]
ys <- ys[!ys %% 5]
eg <- expand.grid(x = xs, y = ys)
head(eg)
# x y
# 1 2 5
# 2 4 5
# 3 6 5
# 4 2 10
# 5 4 10
# 6 6 10
从这里开始,您可以遍历行:
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
我认为你的output
变量有点偏差,因为&#34; 2,15&#34;应该只包含input$value[1]
(x < 2
是限制因素)。 (存在其他差异。)
无论您的实际索引逻辑是什么,我建议使用此方法,而不是for
或双 - lapply
实现。
NB:
这些命令在功能上等同于此input
:
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
我使用了第一个&#34;代码高尔夫&#34;,但如果您的实际input
data.frame包含其他列,您可能更喜欢第二个更有选择性地选择哪些列非{ {1}}值。
NA
非常适合此类扩展。但是,如果您正在查看明显更大的数据集(包括您的过滤是否比expand.grid
提供的更复杂),那么它可能有点贵,因为它必须在内存中创建整个%%
。 Python在这里使用惰性迭代器会很有用,在这种情况下,您可能更喜欢使用https://stackoverflow.com/a/36144255/3358272(github gist中的扩展函数和一些文档:https://gist.github.com/r2evans/e5531cbab8cf421d14ed)。
答案 1 :(得分:0)
这不是最优雅的解决方案,但你可以用lapply替换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]))
})
})