Как запустить функцию с несколькими аргументами различной длины в цикле в R - PullRequest
0 голосов
/ 11 января 2019

Мне нужно запустить эту функцию 6000 раз со всеми ее итерациями. У меня есть 6 аргументов для функции. Первые 3 из них идут рука об руку и имеют номер 75. Следующий аргумент имеет 9 значений. И последние 2 аргумента имеют 3 значения.

#require dplyr
#data is history as list
matchloop <- function(data, data2, x, a, b, c) {
 #history as list
 split <- data
 #history for reference
 fh <- FullHistory
 #start counter
 n<-1
 #end counter
 m<-a
 tempdf0.3 <- fh
 #set condition for loop
 while(nrow(tempdf0.3) > 1 && m <= (nrow(data2))*b) {
   #put history into a variable
   tempdf0.0 <- split
   #put fh into a variable
   tempdf0.5 <- fh
   #put test path into variable from row n to m
   tempdf0.1 <- as.data.frame(data2[n:m,], stringsAsFactors = FALSE)
   #change column name of test path
   colnames(tempdf0.1) <- "directions"
   #put row n to m of history into variable
   tempdf0.2 <- lapply(tempdf0.0, function(df) df[n:m,])
   #put output into output
   tempdf0.3 <- orderedDistancespos(tempdf0.2, tempdf0.1, 
   "allPaths","directions")
   #add to output routeID based on reference from fh-the test path ID
   tempdf0.3 <- mutate(tempdf0.3, routeID = (subset(tempdf0.5, routeID 
   != x)$routeID))
   #reduce output based on the matched threshold
   tempdf0.3 <- subset(tempdf0.3, dists >= a*c)
   #create new history based on the IDs remaining in output
   split <- split[as.character(tempdf0.3$routeID)]
   #create new history for reference based on the IDs remaining in 
   output
   fh <- subset(fh, routeID %in% tempdf0.3$routeID)
   #increase loop counter
   n <- n+a
   #increase loop counter
   m <- n+(a-1)
 }
#show output
mylist <- list(tempdf0.3, nrow(tempdf0.3))
return(mylist)
}

Я попытался поместить 3 аргумента с 75 элементами в их собственных списках и использовать mapply. Это работает. Но даже на этом уровне мне все еще нужно выполнить код 81 раз, чтобы охватить все переменные, потому что, насколько я понимаю, mapply перезагружается, основываясь на длине самого длинного аргумента.

mapply(matchloop, mylist2,mylist3,mylist4, MoreArgs = list(a=a, b=b, c=c))

данные - это список фреймов данных

data2 - это фрейм данных

x, a, b, c - все числовые.

Сейчас я пытаюсь упорядочить вывод, чтобы он был всего в 1 строке. Так что, если возможно, я бы хотел 1 вывод csv со всеми 6000+ строк.

1 Ответ

0 голосов
/ 16 февраля 2019

Вы можете комбинировать функции mapply и apply для циклического перебора всех возможных комбинаций переменных a, b и c. Для создания всех возможных комбинаций вы можете использовать expand.grid. Наконец, вы можете связать list строк в data.frame с помощью функций do.call и rbind следующим образом:

matchloop_stub <- matchloop <- function(data, data2, x, a, b, c) {
  # stub
  c(d = sum(data), d2 = sum(data2), x = sum(x), a = a, b = b, c = c, r = a + b + c)
}

set.seed(123)
mylist2 <- replicate(75, data.frame(rnorm(1)))
mylist3 <- replicate(75, data.frame(rnorm(2)))
mylist4 <- replicate(75, data.frame(rnorm(3)))
a <- 1:9 
b <- 1:3
c <- 1:3
abc <- expand.grid(a, b, c)
names(abc) <- c("a", "b", "c")
xs <- apply(abc, 1, function(x) (mapply(matchloop_stub, mylist2, mylist3, mylist4, x[1], x[2], x[3], SIMPLIFY = FALSE)))
df <- do.call(rbind, do.call(rbind, xs))

write.csv(df, file = "temp.csv")
res <- read.csv("temp.csv")
nrow(res)
# [1] 6075

head(res)
#   X          d        d2         x a b c r
# 1 1 -0.5604756 0.7407984 -1.362065 1 1 1 3
# 2 2 -0.5604756 0.7407984 -1.362065 2 1 1 4
# 3 3 -0.5604756 0.7407984 -1.362065 3 1 1 5
# 4 4 -0.5604756 0.7407984 -1.362065 4 1 1 6
# 5 5 -0.5604756 0.7407984 -1.362065 5 1 1 7
# 6 6 -0.5604756 0.7407984 -1.362065 6 1 1 8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...