[英]R nested for loop structure for all combinations of two variables
I want to run a function on each level of a data.frame variable based on the condition of each level of another data.frame variable (or lists, if it's better to work with them for some reason). 我想根据另一个data.frame变量(或列表,如果出于某种原因最好与它们一起使用)的每个级别的条件,在data.frame变量的每个级别上运行一个函数。
If one of the variables achieves a certain condition (eg, > 15), I then want to run a simple function (eg, product) on each pair of variables and add the results to a new list. 如果其中一个变量达到某个条件(例如> 15),那么我想在每对变量上运行一个简单函数(例如product)并将结果添加到新列表中。 For the sake of my needs and other's future needs, I am hoping for a solution that is flexible for any condition and any function.
为了我的需要和其他人的未来需求,我希望有一个对任何条件和任何功能都灵活的解决方案。
I am new to programming/R and do not know how to appropriate structure a for loop (or other method) in order to run the function for all combinations of elements in both data.frame variables. 我是Programming / R的新手,并且不知道如何适当构造for循环(或其他方法)以便为两个data.frame变量中的元素的所有组合运行函数。 It seems like this should be really easy to achieve but I've been searching for hours and cannot find a solution.
看起来这确实应该很容易实现,但是我已经花了好几个小时才找到解决方案。
This is the nested for loop code I am working on: 这是我正在处理的嵌套的for循环代码:
df1 <- data.frame(c(1, 2, 3))
df2 <- data.frame(c(10, 20, 30))
list1 <- list()
for (i in 1:length(df1)) {
for (j in 1:length(df2)) {
if (df2[j,] > 15) {
list1[[i]] <- df1[i,] * df2[j,]}
}}
list1
When I run the current code I get and empty list results: list(). 当我运行当前代码时,我得到并清空列表结果:list()。 What I want returned is something like this:
我想要返回的是这样的:
[[1]]
[1] 20
[[2]]
[1] 30
[[3]]
[1] 40
[[4]]
[1] 60
[[5]]
[1] 60
[[6]]
[1] 90
Consider sapply
with two inputs to iterate across nrow
of both data frames with list conversion: 考虑
sapply
具有两个输入跨遍历nrow
带有表转换的两个数据帧:
mat <- sapply(1:nrow(df2), function(i, j) ifelse(df2[j,] > 15, df1[i,]*df2[j,], NA),
1:nrow(df1))
mat <- mat[!is.na(mat)]
mat
# [1] 20 30 40 60 60 90
as.list(mat)
# [[1]]
# [1] 20
#
# [[2]]
# [1] 30
#
# [[3]]
# [1] 40
#
# [[4]]
# [1] 60
#
# [[5]]
# [1] 60
#
# [[6]]
# [1] 90
There are many ways to do this, here are two of them: one is your for
loop and another is vectorised. 有许多方法可以做到这一点,其中有两种:一种是
for
循环,另一种是矢量化。
for
loop for
循环
There are few mistakes in your code, both df1
and df2
have length
= 1. Therefore, i
and j
are only set as 1. This can be fixed by using nrow
instead of length
. 您的代码中几乎没有错误,
df1
和df2
length
均为1。因此, i
和j
仅设置为1。这可以通过使用nrow
而不是length
。 Another thing is to create an index
outside the loop to assign your results to list. 另一件事是在循环外创建
index
以将结果分配给列表。 Following code works 以下代码有效
df1 <- data.frame(c(1, 2, 3))
df2 <- data.frame(c(10, 20, 30))
list1 <- list()
index=0
for (i in 1:nrow(df1)) {
for (j in 1:nrow(df2)) {
if (df2[j,] > 15) {
index=index+1
list1[[index]] <- df1[i,] * df2[j,]}
}}
list1
[[1]]
[1] 20
[[2]]
[1] 30
[[3]]
[1] 40
[[4]]
[1] 60
[[5]]
[1] 60
[[6]]
[1] 90
vectorized way 向量化方式
Using expand.grid
to generate the required combinations and prod
to find their products 使用
expand.grid
产生所需的组合和prod
找到自己的产品
dat=expand.grid(df1[,1], df2[df2 > 15,1])
dat=dat[order(dat$Var1),]
apply(dat, 1, prod)
1 4 2 5 3 6
20 30 40 60 60 90
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.