R-order()每隔一次运行就会弄乱顺序

时间:2019-04-17 09:26:43

标签: r sorting

我正在与学校的强制性作业一起工作,并尝试根据具有顺序的列之一对我的数据框进行排序(请参见代码)。第一次,它运行良好,但是下次,我运行代码时,订单混乱了。现在,每隔一段时间我运行一次代码,它一次正确排序,而下次又混乱了。可能只是一些小错误,或对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 :(得分:0)

您遇到的原因很可能是由多个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)

现在您说的是您的问题每隔两次发生一次,因此这似乎是最可能的原因。从您的代码中,如果DT中包含x,则您将在运行代码之前附加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. 没有错误,因为已附加xDT现在将被排序,然后再次附加
  3. 在第三次运行时,如果尚未分离DT,则已排序的x将附加在pos = 2处,因此将用于对数据进行排序(但{{1} }已经排序,所以什么也没发生

对于(1),请注意,在您的代码中

x

由于这种附着是在订购之后进行的,因此第一次运行时可能会导致错误。

对于(2-3),更容易可视化:将代码重新运行2次以上(第一次运行之后),将类似于运行以下代码。这使“第二次问题”形象化。在代码中,我删除了较少的相关错误,并产生了可读性警告(但是有多个警告)

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

attach(training)
  

order(x)中的错误:找不到对象'x'

第二次打印:(第一个失败)

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
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。因此,对其进行排序不会改变其顺序。这可能是您的问题。

现在我已经多次附加了数据,并且需要注意的重要一点是,它产生的所有警告都是许多经验丰富的R用户避免使用x的原因。让我们尝试再次运行attach:

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 ,基本上有4层变量和全局环境:

  1. 全球环境pos = 5
  2. 我们刚刚运行的第四个附件(pos = 1)
  3. 循环(pos = 2)中的第三个附件
  4. 循环(pos = 3)中的第二个附件
  5. 循环(pos = 2)中的第一个附件

这是要记住(pos = 3)使用完附加数据后的另一个原因(如果多次附加detach,则detach次重复使用)。

pos - 1

原则上,如果您有足够的内存,并且记得记住replicate(4, detach(DT)) 数据,则一切正常。但是请记住,使用detach不会分离框架,如下所示:

rm(list = ls())

因此,分离是使用attach(DT) rm(list=ls()) x >2 6 3 4 1 5 的任何过程的必需步骤。

对于您的特定问题,向上移动attach并在底部向下添加attach(training)应该可以解决问题。