r - R - order() 每隔一次运行就会弄乱顺序
问题描述
我正在处理学校的强制性作业,并尝试根据其中一列的顺序对我的数据框进行排序(请参阅代码)。它第一次运行得很好,但是下次我运行代码时,顺序就搞砸了。现在,每隔一次我运行代码时,它就被正确地订购了一次,而下一次就搞砸了。可能只是一些小错误,或者对 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),]
解决方案
您遇到的情况可能是由多个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
声明之后,因此每次运行都会发生以下事情:
- 第一次运行:你得到一个错误,因为没有附加
x
. - 没有错误,因为
x
已经附加DT
了,现在要排序,然后再附加 - 在第三次运行时,如果您没有 detached
DT
,则 sortedx
将附加在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层变量和全局环境:
- 全球环境
(pos = 1)
- 第四个附件,我们刚刚运行的
(pos = 2)
- 循环中的第三个附件
(pos = 3)
- 循环中的第二个附件
(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)
添加向下应该可以解决问题。detach(training)
推荐阅读
- r - How to fix if else output in terms of assigning NAs to unknown
- react-native - React Native:如何使用 DeviceInfo isTablet() 方法有条件地将样式应用于元素?
- android - 尝试将 Firebase 添加到我的 android 项目时出现 gradle 同步错误 JAVA_LETTER_OR_DIGIT
- android - OpenCV Utils.matToBitmap:断言失败 AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0 如果位图是使用 ImageDecoder.createSource 创建的
- c# - 在什么情况下 .NET 方法的执行可能会被另一个方法中断
- odata - 新会话开始时保存全局属性值
- javascript - 从 URL 获取特定数据
- javascript - 如何在ajax调用或表单调用后保留使用Jquery所做的CSS更改
- javascript - Express 中的并发
- html - 如何用下拉菜单固定标题?