Вложено для структуры цикла для всех комбинаций двух переменных - PullRequest
0 голосов
/ 03 апреля 2019

Я хочу запустить функцию на каждом уровне переменной data.frame в зависимости от состояния каждого уровня другой переменной data.frame (или списков, если по какой-то причине с ними лучше работать).

Если одна из переменных достигает определенного условия (например,> 15), я хочу запустить простую функцию (например, product) для каждой пары переменных и добавить результаты в новый список. Ради своих потребностей и будущих потребностей, я надеюсь на Гибкое решение для любых условий и любых функций.

Я новичок в программировании / R и не знаю, как правильно структурировать цикл for (или другой метод), чтобы запустить функцию для всех комбинаций элементов в обеих переменных data.frame. Кажется, что это должно быть действительно легко достичь, но я искал часы и не могу найти решение.

Это вложенный код цикла, над которым я работаю:

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 ]

1 голос
/ 03 апреля 2019

Есть много способов сделать это, вот два из них: один - ваш for цикл, а другой - векторизация.

for петля

В вашем коде есть несколько ошибок, и df1, и df2 имеют length = 1. Поэтому i и j устанавливаются только как 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 
1 голос
/ 03 апреля 2019

Рассмотрим 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
...