Как написать вложенный для l oop, чтобы внутренний l oop не перезаписывал первые значения l oop - PullRequest
1 голос
/ 24 апреля 2020

Новый постер на Stackoverflow, но долгое время просмотра. Я не смог найти ни одной предыдущей публикации, в которой был задан мой c вопрос.

По сути, я борюсь с тем, как использовать вложенную for l oop для моей проблемы. Проблема в том, что количество переменных и результатов будет меняться в зависимости от варианта использования, поэтому я хочу решение, которое будет гибким для различных перестановок. Я не уверен, что apply поможет мне, потому что я не знаю заранее, сколько переменных и результатов будет в каждом конкретном случае использования.

Цель состоит в том, чтобы классифицировать, правильно ли прогнозируется результат переменная (tp = истинно положительный, и т. д. c).

Проблема в том, что внутреннее значение l oop приводит к перезаписи внешних значений l oop, но я хочу, чтобы для каждого outcome оценивается по каждому variable один раз независимо. Не уверен, что лучший способ сделать это, и любые советы приветствуются.

#Repex code

#Generate variable
variable <- c(1,2,3)
df <- as.data.frame(matrix(0, ncol = 0, nrow = 30))
for(i in 1:length(variable)){
  df[,c(paste0("variable",variable[i]))]<-as.vector(sample(c(0,1), replace=TRUE, size=30))
}
df

#Generate outcome
outcome <- c(1,2,3)
df2 <- as.data.frame(matrix(0, ncol = 0, nrow = 30))
for(i in 1:length(outcome)){
  df2[,c(paste0("outcome",outcome[i]))]<-as.vector(sample(c(0,1), replace=TRUE, size=30))
}
df2

#Generate performance metrics of outcome and predictor
for (i in variable){
  for(j in 1:length(df2)){
    df[, c(paste0("tp.",variable[i]))] <- as.vector(ifelse(df[, c(paste0("variable",variable[i]))]==1 & df2[j]==1,1,0))
    df[, c(paste0("tn.",variable[i]))] <- as.vector(ifelse(df[, c(paste0("variable",variable[i]))]==0 & df2[j]==0,1,0))
    df[, c(paste0("fp.",variable[i]))] <- as.vector(ifelse(df[, c(paste0("variable",variable[i]))]==1 & df2[j]==0,1,0))
    df[, c(paste0("fn.",variable[i]))] <- as.vector(ifelse(df[, c(paste0("variable",variable[i]))]==0 & df2[j]==1,1,0))
  }
}
df

#bind the data for comparison and spot checking
df3 <- cbind(df2,df)

#here we see that only the final inner loop data are correct
df3

1 Ответ

0 голосов
/ 24 апреля 2020

Проблема в том, что у вас есть 3 разных variable с, которые вы хотите сравнить с 3 разными outcome с, поэтому вы делаете 9 сравнений. Однако, поскольку вы маркируете свои столбцы только в соответствии с variable, у вас есть только три уникальных суффикса чисел c (по одному для каждого значения i), вставленных в каждую статистику c (tp, tn, fp и фн). Поэтому у вас есть только 12 различных имен столбцов.

Вы ни в коем случае не помечаете столбцы как по переменной, так и по результату. Это означает, что каждый раз, когда ваш внутренний l oop увеличивается до следующей переменной результата, вы перезаписываете столбец в df, который вы написали на предыдущей итерации l oop.

In в любом случае, как вы собираетесь отслеживать, какое сравнение вы проводите, если только вы не используете оба номер переменной и номер результата для обозначения столбцов?

Таким образом, вы могли бы сделать это следующим образом:

for (i in variable)
{
  V <- c(paste0("variable", i))
  for(j in seq_along(df2))
  {
    comp <- paste0(i, ".vs.", j)
    df[paste0("tp.", comp)] <- as.numeric(df[V] == 1 & df2[j] == 1)
    df[paste0("tn.", comp)] <- as.numeric(df[V] == 0 & df2[j] == 0)
    df[paste0("fp.", comp)] <- as.numeric(df[V] == 1 & df2[j] == 0)
    df[paste0("fn.", comp)] <- as.numeric(df[V] == 0 & df2[j] == 1)
  }
}

df3 <- cbind(df2, df)

Что даст вам структуру, которую вы искали. Это большой фрейм данных, поэтому мы просто посмотрим на него с помощью str:

str(df3)
#> 'data.frame':    30 obs. of  42 variables:
#>  $ outcome1 : num  0 1 1 1 1 0 1 0 1 1 ...
#>  $ outcome2 : num  0 0 0 0 1 0 0 1 1 1 ...
#>  $ outcome3 : num  1 1 0 0 0 0 0 0 1 0 ...
#>  $ variable1: num  0 1 0 0 1 1 0 1 1 1 ...
#>  $ variable2: num  1 1 0 0 0 0 0 0 0 0 ...
#>  $ variable3: num  1 0 0 0 1 0 0 1 0 0 ...
#>  $ tp.1.vs.1: num  0 1 0 0 1 0 0 0 1 1 ...
#>  $ tn.1.vs.1: num  1 0 0 0 0 0 0 0 0 0 ...
#>  $ fp.1.vs.1: num  0 0 0 0 0 1 0 1 0 0 ...
#>  $ fn.1.vs.1: num  0 0 1 1 0 0 1 0 0 0 ...
#>  $ tp.1.vs.2: num  0 0 0 0 1 0 0 1 1 1 ...
#>  $ tn.1.vs.2: num  1 0 1 1 0 0 1 0 0 0 ...
#>  $ fp.1.vs.2: num  0 1 0 0 0 1 0 0 0 0 ...
#>  $ fn.1.vs.2: num  0 0 0 0 0 0 0 0 0 0 ...
#>  $ tp.1.vs.3: num  0 1 0 0 0 0 0 0 1 0 ...
#>  $ tn.1.vs.3: num  0 0 1 1 0 0 1 0 0 0 ...
#>  $ fp.1.vs.3: num  0 0 0 0 1 1 0 1 0 1 ...
#>  $ fn.1.vs.3: num  1 0 0 0 0 0 0 0 0 0 ...
#>  $ tp.2.vs.1: num  0 1 0 0 0 0 0 0 0 0 ...
#>  $ tn.2.vs.1: num  0 0 0 0 0 1 0 1 0 0 ...
#>  $ fp.2.vs.1: num  1 0 0 0 0 0 0 0 0 0 ...
#>  $ fn.2.vs.1: num  0 0 1 1 1 0 1 0 1 1 ...
#>  $ tp.2.vs.2: num  0 0 0 0 0 0 0 0 0 0 ...
#>  $ tn.2.vs.2: num  0 0 1 1 0 1 1 0 0 0 ...
#>  $ fp.2.vs.2: num  1 1 0 0 0 0 0 0 0 0 ...
#>  $ fn.2.vs.2: num  0 0 0 0 1 0 0 1 1 1 ...
#>  $ tp.2.vs.3: num  1 1 0 0 0 0 0 0 0 0 ...
#>  $ tn.2.vs.3: num  0 0 1 1 1 1 1 1 0 1 ...
#>  $ fp.2.vs.3: num  0 0 0 0 0 0 0 0 0 0 ...
#>  $ fn.2.vs.3: num  0 0 0 0 0 0 0 0 1 0 ...
#>  $ tp.3.vs.1: num  0 0 0 0 1 0 0 0 0 0 ...
#>  $ tn.3.vs.1: num  0 0 0 0 0 1 0 0 0 0 ...
#>  $ fp.3.vs.1: num  1 0 0 0 0 0 0 1 0 0 ...
#>  $ fn.3.vs.1: num  0 1 1 1 0 0 1 0 1 1 ...
#>  $ tp.3.vs.2: num  0 0 0 0 1 0 0 1 0 0 ...
#>  $ tn.3.vs.2: num  0 1 1 1 0 1 1 0 0 0 ...
#>  $ fp.3.vs.2: num  1 0 0 0 0 0 0 0 0 0 ...
#>  $ fn.3.vs.2: num  0 0 0 0 0 0 0 0 1 1 ...
#>  $ tp.3.vs.3: num  1 0 0 0 0 0 0 0 0 0 ...
#>  $ tn.3.vs.3: num  0 0 1 1 0 1 1 0 0 1 ...
#>  $ fp.3.vs.3: num  0 0 0 0 1 0 0 1 0 0 ...
#>  $ fn.3.vs.3: num  0 1 0 0 0 0 0 0 1 0 ...

Другой (и, возможно, более разумный) способ сделать это - иметь 3 фрейма данных, по одному на каждый переменная, и каждый с двенадцатью столбцами (три набора tp, tn, fp, fn). Вы можете сделать это легко, используя lapply:

df_list <- lapply(df, function(x)
{
  dfs <- list()
  for(j in seq_along(df2))
  {
    dfs[[j]] <- data.frame(ifelse(x == 1 & df2[j] == 1, 1, 0),
                           ifelse(x == 0 & df2[j] == 0, 1, 0),
                           ifelse(x == 1 & df2[j] == 0, 1, 0),
                           ifelse(x == 0 & df2[j] == 1, 1, 0))
  }
  setNames(do.call("cbind", dfs), 
           paste0(c("tp.", "tn.", "fp.", "fn."), rep(seq_along(df2), each = 4)))
})

, что дает вам:

df_list
#> $variable1
#>    tp.1 tn.1 fp.1 fn.1 tp.2 tn.2 fp.2 fn.2 tp.3 tn.3 fp.3 fn.3
#> 1     0    1    0    0    0    1    0    0    0    0    0    1
#> 2     1    0    0    0    0    0    1    0    1    0    0    0
#> 3     0    0    0    1    0    1    0    0    0    1    0    0
#> 4     0    0    0    1    0    1    0    0    0    1    0    0
#> 5     1    0    0    0    1    0    0    0    0    0    1    0
#> 6     0    0    1    0    0    0    1    0    0    0    1    0
#> 7     0    0    0    1    0    1    0    0    0    1    0    0
#> 8     0    0    1    0    1    0    0    0    0    0    1    0
#> 9     1    0    0    0    1    0    0    0    1    0    0    0
#> 10    1    0    0    0    1    0    0    0    0    0    1    0
#> 11    0    1    0    0    0    0    0    1    0    0    0    1
#> 12    0    0    1    0    1    0    0    0    1    0    0    0
#> 13    0    0    0    1    0    1    0    0    0    1    0    0
#> 14    0    1    0    0    0    0    0    1    0    0    0    1
#> 15    0    0    0    1    0    1    0    0    0    0    0    1
#> 16    0    1    0    0    0    1    0    0    0    0    0    1
#> 17    0    0    1    0    1    0    0    0    1    0    0    0
#> 18    0    0    1    0    0    0    1    0    0    0    1    0
#> 19    0    0    1    0    0    0    1    0    0    0    1    0
#> 20    1    0    0    0    0    0    1    0    1    0    0    0
#> 21    0    1    0    0    0    1    0    0    0    1    0    0
#> 22    1    0    0    0    0    0    1    0    1    0    0    0
#> 23    0    0    0    1    0    1    0    0    0    0    0    1
#> 24    0    0    0    1    0    1    0    0    0    0    0    1
#> 25    0    0    1    0    0    0    1    0    0    0    1    0
#> 26    0    0    1    0    0    0    1    0    0    0    1    0
#> 27    1    0    0    0    1    0    0    0    0    0    1    0
#> 28    0    0    1    0    0    0    1    0    1    0    0    0
#> 29    0    0    0    1    0    1    0    0    0    1    0    0
#> 30    0    0    1    0    0    0    1    0    0    0    1    0
#> 
#> $variable2
#>    tp.1 tn.1 fp.1 fn.1 tp.2 tn.2 fp.2 fn.2 tp.3 tn.3 fp.3 fn.3
#> 1     0    0    1    0    0    0    1    0    1    0    0    0
#> 2     1    0    0    0    0    0    1    0    1    0    0    0
#> 3     0    0    0    1    0    1    0    0    0    1    0    0
#> 4     0    0    0    1    0    1    0    0    0    1    0    0
#> 5     0    0    0    1    0    0    0    1    0    1    0    0
#> 6     0    1    0    0    0    1    0    0    0    1    0    0
#> 7     0    0    0    1    0    1    0    0    0    1    0    0
#> 8     0    1    0    0    0    0    0    1    0    1    0    0
#> 9     0    0    0    1    0    0    0    1    0    0    0    1
#> 10    0    0    0    1    0    0    0    1    0    1    0    0
#> 11    0    1    0    0    0    0    0    1    0    0    0    1
#> 12    0    0    1    0    1    0    0    0    1    0    0    0
#> 13    0    0    0    1    0    1    0    0    0    1    0    0
#> 14    0    0    1    0    1    0    0    0    1    0    0    0
#> 15    1    0    0    0    0    0    1    0    1    0    0    0
#> 16    0    0    1    0    0    0    1    0    1    0    0    0
#> 17    0    1    0    0    0    0    0    1    0    0    0    1
#> 18    0    0    1    0    0    0    1    0    0    0    1    0
#> 19    0    0    1    0    0    0    1    0    0    0    1    0
#> 20    1    0    0    0    0    0    1    0    1    0    0    0
#> 21    0    1    0    0    0    1    0    0    0    1    0    0
#> 22    0    0    0    1    0    1    0    0    0    0    0    1
#> 23    0    0    0    1    0    1    0    0    0    0    0    1
#> 24    1    0    0    0    0    0    1    0    1    0    0    0
#> 25    0    0    1    0    0    0    1    0    0    0    1    0
#> 26    0    0    1    0    0    0    1    0    0    0    1    0
#> 27    1    0    0    0    1    0    0    0    0    0    1    0
#> 28    0    0    1    0    0    0    1    0    1    0    0    0
#> 29    0    0    0    1    0    1    0    0    0    1    0    0
#> 30    0    0    1    0    0    0    1    0    0    0    1    0
#> 
#> $variable3
#>    tp.1 tn.1 fp.1 fn.1 tp.2 tn.2 fp.2 fn.2 tp.3 tn.3 fp.3 fn.3
#> 1     0    0    1    0    0    0    1    0    1    0    0    0
#> 2     0    0    0    1    0    1    0    0    0    0    0    1
#> 3     0    0    0    1    0    1    0    0    0    1    0    0
#> 4     0    0    0    1    0    1    0    0    0    1    0    0
#> 5     1    0    0    0    1    0    0    0    0    0    1    0
#> 6     0    1    0    0    0    1    0    0    0    1    0    0
#> 7     0    0    0    1    0    1    0    0    0    1    0    0
#> 8     0    0    1    0    1    0    0    0    0    0    1    0
#> 9     0    0    0    1    0    0    0    1    0    0    0    1
#> 10    0    0    0    1    0    0    0    1    0    1    0    0
#> 11    0    1    0    0    0    0    0    1    0    0    0    1
#> 12    0    1    0    0    0    0    0    1    0    0    0    1
#> 13    1    0    0    0    0    0    1    0    0    0    1    0
#> 14    0    1    0    0    0    0    0    1    0    0    0    1
#> 15    0    0    0    1    0    1    0    0    0    0    0    1
#> 16    0    0    1    0    0    0    1    0    1    0    0    0
#> 17    0    0    1    0    1    0    0    0    1    0    0    0
#> 18    0    1    0    0    0    1    0    0    0    1    0    0
#> 19    0    1    0    0    0    1    0    0    0    1    0    0
#> 20    1    0    0    0    0    0    1    0    1    0    0    0
#> 21    0    0    1    0    0    0    1    0    0    0    1    0
#> 22    0    0    0    1    0    1    0    0    0    0    0    1
#> 23    1    0    0    0    0    0    1    0    1    0    0    0
#> 24    0    0    0    1    0    1    0    0    0    0    0    1
#> 25    0    1    0    0    0    1    0    0    0    1    0    0
#> 26    0    1    0    0    0    1    0    0    0    1    0    0
#> 27    1    0    0    0    1    0    0    0    0    0    1    0
#> 28    0    0    1    0    0    0    1    0    1    0    0    0
#> 29    1    0    0    0    0    0    1    0    0    0    1    0
#> 30    0    0    1    0    0    0    1    0    0    0    1    0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...