R嵌套两个变量的所有组合的循环结构

时间:2019-04-02 22:12:56

标签: r loops dataframe nested apply

我想根据另一个data.frame变量(或列表,如果出于某种原因最好与它们一起使用)的每个级别的条件,在data.frame变量的每个级别上运行一个函数。

如果其中一个变量达到某个条件(例如> 15),那么我想在每对变量上运行一个简单函数(例如product),然后将结果添加到新列表中。为了我的需求和他人的未来需求,我希望 对于任何条件和任何功能都灵活的解决方案。

我是Programming / R的新手,并且不知道如何为循环(或其他方法)构造适当的结构,以便为两个data.frame变量中的元素的所有组合运行函数。看起来这确实应该很容易实现,但是我已经花了好几个小时才找到解决方案。

这是我正在处理的嵌套的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

运行当前代码时,我得到并清空列表结果:list()。 我想要返回的是这样的:

[[1]]
[1] 20

[[2]]
[1] 30

[[3]]
[1] 40

[[4]]
[1] 60

[[5]]
[1] 60

[[6]]
[1] 90

2 个答案:

答案 0 :(得分:1)

考虑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

答案 1 :(得分:1)

执行此操作的方法很多,这里有两种:一种是您的for循环,另一种是矢量化的。

for循环

您的代码中几乎没有错误,df1df2都具有length =1。因此,ij仅设置为1可以通过使用nrow而不是length来解决。另一件事是在循环外创建一个index,以将结果分配给列表。以下代码有效

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

矢量化方式

使用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