R: Подписанные присвоения не перезаписывают значения или не изменяют все значения (наполовину выяснено) - PullRequest
0 голосов
/ 15 февраля 2020

У меня была проблема в моем коде R, который время от времени появляется, когда я попытаюсь перезаписать значения переменной, используя подписанное присваивание, и некоторые / все значения не перезаписываются. (С тех пор я выяснил половину проблемы, но вторая половина вопроса все еще применима.)

Вот упрощенный пример кода, который сравнивает две переменные, чтобы увидеть, какая из них больше, а затем находит места, где они равны, и устанавливает переменную «больше» в -1, чтобы указать, что ни один из них не больше.

a <- rep(0:2,96)
b <- rep(0:3,72)
dataset <- data.frame(cbind(a,b))
dim(dataset) # Show dimensions

> [1] 288   2

# Add a few random NAs
dataset$a[15] <- NA
dataset$b[27] <- NA
dataset$a_bigger <- (dataset$a > dataset$b)
dataset$b_bigger <- (dataset$b > dataset$a)
table(dataset[,c('a_bigger','b_bigger')],useNA='ifany')

>        b_bigger
>a_bigger FALSE TRUE <NA>
>   FALSE    70  144    0
>   TRUE     72    0    0
>   <NA>      0    0    2

dataset$same <- (dataset$a == dataset$b) # Find values where they are the same and neither is bigger
table(dataset$same,useNA='ifany') # Show that there are NAs in dataset$same.

> FALSE  TRUE  <NA>
>  216    70     2

dataset$same[is.na(dataset$a) | is.na(dataset$b)] <- 0 # Fix the NAs. A and B can't be the same if one of them is NA.
table(dataset$same,useNA='ifany') # Show that there are no longer NAs

>   0   1
> 218  70

dataset$a_bigger[dataset$same] <- -1
dataset$b_bigger[dataset$same] <- -1
table(dataset[,c('a_bigger','b_bigger')],useNA='ifany') # Wait, there should be 70 changed, not 1...?

>         b_bigger
> a_bigger  -1   0   1 <NA>
>    -1     1   0   0    0
>    0      0  69 144    0
>    1      0  72   0    0
>    <NA>   0   0   0    2

До этого момента я выяснил, что произошло. Установка нескольких значений «same» в 0 изменила его с логического true / false на 0/1, а затем, когда я использовал его для индексации другой переменной, «1» воспринимались как «перезаписать первую строку», а не как логические истины.

Это меня смутило, поскольку в других контекстах R будет рассматривать 0/1 как эквивалентное истине / ложью (фактически, если я переписываю строку присваивания как dataset$a_bigger[dataset$same & dataset$same] <- -1, это работает) но, по крайней мере, я могу понять, что происходит сейчас.

Но я все еще не понимаю, почему это происходит:

dataset$even_weirder[dataset$same] <- -1 # But now if I do the assignment on a column/variable that's not initialized...
table(dataset[,'even_weirder'],useNA='ifany') # They all change!!!

>  -1
> 288

Если он действительно так думает, когда я пишу dataset$somevar[dataset$same] Я имею в виду позицию 0 (которую он игнорирует) и позицию 1 (которую он перезаписывает снова и снова), а затем, когда я делаю это с неинициализированным столбцом, почему он присваивает -1 каждой строке вместо того, чтобы назначать ее первой грести и уходить от остальных нет?

1 Ответ

0 голосов
/ 15 февраля 2020

Проблема в основном

class(dataset$same)
#[1] "numeric"

, что не логично, а двоично, т.е. 0 и 1

head(dataset$same)
#[1] 1 1 1 0 0 0

Вместо этого должно быть

as.logical(dataset$same)

Поскольку назначение происходит в позиции индекса 1, т.е. значение -1 обновляется в 1-м элементе, а не где-либо еще

dataset$a_bigger[as.logical(dataset$same)] <- -1
dataset$b_bigger[as.logical(dataset$same)] <- -1

table(dataset[,c('a_bigger','b_bigger')],useNA='ifany')
#        b_bigger
#a_bigger  -1   0   1 <NA>
#    -1    70   0   0    0   #### 70 is showing up now
#    0      0   0 144    0
#    1      0  72   0    0
#    <NA>   0   0   0    2

Что касается Even_weider, оно создается на лету и из-за первый элемент, назначенный -1, возвращается на всю длину столбца

dataset$even_weirder[dataset$same]
#NULL
dataset$even_weirder[dataset$same] <- -1
sum(dataset$same)
#[1] 70
table(dataset[,'even_weirder'],useNA='ifany')

# -1 
#288 
dataset$even_weirder
#  [1] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
# [39] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
# [77] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
#[115] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
#[153] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
#[191] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
#[229] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
#[267] -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...