R - order () портит порядок при каждом другом запуске - PullRequest
0 голосов
/ 17 апреля 2019

Я работаю с обязательным заданием для школы и пытаюсь отсортировать свой фрейм данных по одному из столбцов с порядком (см. Код). Это сработало отлично в первый раз, однако в следующий раз, когда я запустил код, порядок был испорчен. И теперь, каждый раз, когда я запускаю код, он правильно заказан один раз, а в следующий раз испорчен. Возможно, просто небольшая ошибка или недоразумение о том, как переменная работает в R, может кто-нибудь помочь?

Если вы запустите код, вы легко увидите, что график меняется от красивой красной кривой к хаосу паутины от пробежки к пробежке.

dataset <- read.table("https://www.uio.no/studier/emner/matnat/math/STK2100/v19/mandatoryassignments-exam/data.dat")

set.seed(1)
samplesize <- round(nrow(dataset)/2)
samp <- sample(seq_len(nrow(dataset)), size = samplesize)
training <- dataset[samp, ]
test <- dataset[-samp, ]
training <- training[order(x),]
test <- test[order(x),]

attach(training)
library(caret)
ctrl <- trainControl(method="cv",number = 5)
knn <- train(y ~ x, data = training, metric = "Rsquared", method = "knn", trControl = ctrl)

knn
y.pred = predict(knn,newdata = x)
plot(training)
lines(x, y.pred, col='red')

Я решил проблему путем обмена

training <- training[order(x),]
#with
training <- training[order(training$x),]

1 Ответ

0 голосов
/ 17 апреля 2019

То, что вы испытываете, вероятно, вызвано несколькими attach утверждениями. Давайте возьмем пример, чтобы попытаться определить проблему.

set.seed(1)
n <- 6
DT <- data.frame(letters = LETTERS[1:6], numbers = 6:1, x = sample(1:6))
head(DT)

  letters numbers x
1       A       6 2
2       B       5 6
3       C       4 3
4       D       3 4
5       E       2 1
6       F       1 5

Теперь я предполагаю, что x содержится в ваших данных, но, скорее всего, у вас где-то есть переменная. Он не включен в ваш код, поэтому я только догадываюсь, и в любом случае это был вектор length <= nrow(DT).

Задача 1: attach(x)

Теперь вы говорите, что ваша проблема возникает через раз, так что, похоже, это наиболее вероятная причина. Из вашего кода, если x содержится в DT, вы присоединяете свой data.frame перед запуском кода:

attach(DT)
DT <- DT[order(x),]
head(DT)

  letters numbers x
5       E       2 1
1       A       6 2
3       C       4 3
4       D       3 4
6       F       1 5
2       B       5 6

Это правильно упорядочивает наш data.frame.

теперь, если вы снова запустите код, чаще всего люди очищают память, выполняя rm(list=ls()), чтобы очистить все переменные. Если вы делаете заказ, то все должно работать нормально, но большинство пользователей R предлагают не использовать attach, и давайте просто быстро покажем одну причину:

rm(list=ls()) #remove everything we can see
x
print(x)

[1] 2 6 3 4 1 5

Как и удивительно для большинства новых пользователей R, «x», «буквы» и «цифры» все еще существуют в качестве переменных. Чтобы удалить их, вам нужно будет запустить detach(DT) даже после запуска rm(list=ls()). Можно использовать attach, если вы помните это, и данные не слишком велики.

Теперь рассмотрим возможность повторного запуска вашего кода. Вы attach выписываете после вашего order выписки, поэтому при каждом запуске будут происходить следующие вещи:

  1. Первый запуск: вы получаете ошибку, так как нет прикрепленных x.
  2. Нет ошибок, поскольку x был прикреплен DT теперь будет отсортирован, а затем присоединен снова
  3. При третьем запуске, если вы не отсоединили DT, отсортированный x будет прикреплен на pos = 2 и, таким образом, будет использоваться для упорядочения ваших данных (но x уже отсортирован, поэтому ничего не происходит )

Для (1) обратите внимание, что в вашем коде

training <- training[order(x),]
test <- test[order(x),]

attach(training)

Поскольку такое присоединение идет после заказа, что, вероятно, приведет к ошибке при первом запуске.

Для (2 - 3) проще визуализировать: повторный запуск вашего кода еще 2 раза (после первого запуска) будет аналогичен выполнению кода ниже. Это визуализирует «проблему каждый второй раз». В коде я удалил менее значимые ошибки и выдачи предупреждений для удобства чтения (но их несколько)

for(i in 1:3){ 
    try(
        {
            #Create dataset
            set.seed(1)
            n <- 6
            DT <- data.frame(letters = LETTERS[1:6], numbers = 6:1, x = sample(1:6))
            print(x)
            DT <- DT[order(x),] #order data (note the first time it is not attached, eg. produces an error)
            print(DT)
        }
    )
    attach(DT) #attach the current data
}

Ошибка в заказе (x): объект 'x' не найден

Второй отпечаток: (первый сбой)

>x
2 6 3 4 1 5
>DT
  letters numbers x
5       E       2 1
1       A       6 2
3       C       4 3
4       D       3 4
6       F       1 5
2       B       5 6

Третий отпечаток:

>x
1 2 3 4 5 6
>DT
  letters numbers x
1       A       6 2
2       B       5 6
3       C       4 3
4       D       3 4
5       E       2 1
6       F       1 5

В первый раз мы получаем ошибку, потому что x не существует (не было найдено). В следующий раз x был присоединен с DT, и все работает отлично. В третий раз был добавлен x из отсортированного DT и ничего не произошло.

Обратите внимание на вывод, что x отсортирован в третьем отпечатке, так как это прикрепленный x из второго отпечатка. Поэтому сортировка этого не изменит порядок его. Это, вероятно, ваша проблема.

Теперь я приложил данные несколько раз, и важное замечание, которое является причиной того, что многие опытные пользователи R избегают использования attach, - это все предупреждения, которые он выдает. попробуем снова запустить присоединение:

>attach(DT)

The following objects are masked from DT (pos = 3):

    letters, numbers, x

The following objects are masked from DT (pos = 4):

    letters, numbers, x

The following objects are masked from DT (pos = 5):

    letters, numbers, x

The following object is masked from package:base:

    letters

Это предупреждение говорит о том, что было выполнено несколько вложений и что существует несколько переменных с одинаковыми именами (в настоящее время они содержат одни и те же данные). Это даже говорит нам, сколько: pos = 5, в основном есть 4 слоя переменных и глобальная среда:

  1. Глобальная среда (pos = 1)
  2. Четвертая привязанность, которую мы только что запустили (pos = 2)
  3. третье вложение из петли (pos = 3)
  4. Второе вложение из петли (pos = 2)
  5. первое вложение из цикла (pos = 3)

Это еще одна причина, чтобы помнить detach после того, как вы закончили использовать прикрепленные данные (или detach повторно pos - 1 раз, если вы прикрепили их несколько раз).

replicate(4, detach(DT))

В принципе, если у вас достаточно памяти, и вы не забыли detach свои данные, все работает нормально.Но следует помнить, что использование rm(list = ls()) не не * отсоединяет вашу рамку * 1106, как показано ниже:

attach(DT)
rm(list=ls())
x

>2 6 3 4 1 5

Таким образом, отсоединение является обязательным этапом любой процедуры с использованием attach.

Для вашей конкретной проблемы, перемещение attach(training) вверх и добавление detach(training) внизу должно решить проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...