Помещение фрагмента кода в оператор if меняет поведение при назначении - PullRequest
0 голосов
/ 23 января 2019

Я столкнулся с очень любопытной проблемой R. У меня есть фрагмент кода в операторе if, который назначает элементы списка, но он реагирует по-разному, независимо от того, выполняется ли он в операторе if (даже если оператор if if (1==1) {...}) или вне его.

В основном код должен просто делать if (true) {Raw[[1]]$params=params[[1]]; Raw[[2]]$params=params[[2]]; etc..}, но в конце Raw[[1]]$params==Raw[[2]]$params и Raw[[3]]$params==Raw[[4]]$params, но только , если он находится в операторе if (true) {} , Он отлично работает, если не находится внутри оператора if.

Позвольте мне показать пример (это очень упрощенная версия исходного кода; мотивация для rep и назначение списка - по причинам, связанным с управлением переменными, не относящимися к данной проблеме):

#----- Create variables
# params is a 4-element list
params0 <- list(runif(2),runif(4),runif(6),runif(8))
# Raw is a 2-element list, of which every element is another (named) list
Raw0 <- list(list(data=runif(3),params=runif(2)),
             list(data=runif(6),params=runif(6)))

dothing <- TRUE

#----- With if statement - does not correctly assign
Raw <- Raw0
params <- params0

if (dothing) {
  Raw <- rep(Raw,each=2)
  for (x in seq(1,length(params))) {
    Raw[[x]]$params <- params[[x]]
  }
}

# This should be false since params[[1]] ~= params[[2]], but returns true 
identical(Raw[[1]],Raw[[2]])

#----- Without if statement - does correctly assign
Raw <- Raw0
params <- params0

Raw <- rep(Raw,each=2)
for (x in seq(1,length(params))) {
  Raw[[x]]$params <- params[[x]]
}

# This returns false as expected
identical(Raw[[1]],Raw[[2]])

Последняя, ​​очень странная морщина во всем этом - в исходном коде назначение работает нормально, если код выполняется по частям (без пропуска ни одной строки), но неправильно назначается, если весь код выполняется однажды.

Кто-нибудь сможет сказать мне, что мне здесь не хватает? Заранее благодарю за помощь!

1 Ответ

0 голосов
/ 24 января 2019

Наблюдаемое поведение не имеет ничего общего с циклом if.Если вы назначите разные структуры, будет выдано предупреждение «количество заменяемых элементов не кратно длине замены».Я не думаю, что это произошло - в вашем случае, когда к Raw контенту обращаются с использованием $ и заменяют его содержимым params.

> str(Raw[[1]]$params)
 num [1:2] 0.925 0.393
> str(params[[1]])
 num [1:2] 0.177 0.986

#returns the content
> str(Raw[[1]]$params)  #Used in your eg
 num [1:2] 0.949 0.143
> str(Raw[[1]][[2]])    #Equivalent to the one used in your eg
 num [1:2] 0.949 0.143

#returns the type of list 
> str(Raw[[1]]["params"])
List of 1
 $ params: num [1:2] 0.949 0.143

Разница в Raw[[1]]["params"] возвращает listв то время как Raw[[1]]$params или Raw[[1]][[2]] возвращает содержимое.

Но на самом деле это работало бы, когда список того же размера и типа заменяется другим списком (который является правильным кратным длине замены).

Обновленный код:

#----- Create variables
# params is a 4-element list
params0 <- list(runif(2),runif(4),runif(6),runif(8))
# Raw is a 2-element list, of which every element is another (named) list
Raw0 <- list(list(data=runif(3),params=runif(2)),
             list(data=runif(6),params=runif(6)))

dothing <- TRUE

#----- With if statement - does not correctly assign
Raw <- Raw0
params <- params0

if (dothing) {
  Raw <- rep(Raw,each=2)
  for (x in seq(1,length(params))) {
    Raw[[x]]["params"] <- params[x]      ##Note the way list is returned and list is replaced for another list.
  }
}

#CORRECTED returns false: This should be false since params[[1]] ~= params[[2]], but returns true
identical(Raw[[1]],Raw[[2]])
...