在新 R 版本中编译用旧版本编写的代码时出现问题
Posted
技术标签:
【中文标题】在新 R 版本中编译用旧版本编写的代码时出现问题【英文标题】:Problems compiling code written in old version in new R version 【发布时间】:2020-10-21 18:40:43 【问题描述】:我在新版本的 R(4.0.1;平台:x86_64-w64-mingw32/x64(64 位))和 RStudio(版本 1.3.959)中运行命令时遇到问题,这些命令在旧版本中运行良好R.
假设我有一个名为 Check 的表,其中包含 10,000 多行和 100 多个变量(分类和数字)。
如果我尝试调用 droplevels 命令,我会收到以下消息。
Check <- droplevels(Check)
Error in .shallow(x, cols = cols, retain.key = TRUE) :
can't set ALTREP truelength
然而,下面的工作
Check <- rapply(Check, f = droplevels, classes = "factor", how = "replace")
当我尝试通过定义新级别并将其替换为 NA 来替换分类变量中的 NA 时,我收到以下消息:
levels(Check$A) <- c(levels(Check$A), 'unknown.')
# Check$A <- factor(Check$A, levels=c(levels(Check$A), 'unknown.'))
Check$A[is.na(Check$A)] <- 'unknown.'
Error in setalloccol(newx) : can't set ALTREP truelength
当我尝试打开表格时,我收到以下消息:
View(Check)
Error in view: can't set ALTREP truelength
我不明白这里出了什么问题。请问有什么办法吗?
我试过玩
library(tidyverse)
Check <- data.frame(col1 = c(NA, letters[1:10]), col2 = c(NA, NA, 1:8, NA),
col3 = c(NA, letters[1:5], NA, NA, NA, NA, NA))
Test <- Check
Test <- droplevels(Test)
str(Test)
Test2 <- Test[6:11,]
Test2 <- Test2 %>% mutate_if(sapply(Test2, is.character), as.factor)
Test2 <- droplevels(Test2)
以上工作正常,使用dput(Test2)
产生
structure(list(col1 = structure(c(NA, 1L, 2L, 3L, 4L, 5L, 6L,
7L, 8L, 9L, 10L), .Label = c("a", "b", "c", "d", "e", "f", "g",
"h", "i", "j"), class = "factor"), col2 = c(NA, NA, 1L, 2L, 3L,
4L, 5L, 6L, 7L, 8L, NA), col3 = structure(c(6L, 1L, 2L, 3L, 4L,
5L, 6L, 6L, 6L, 6L, 6L), .Label = c("a", "b", "c", "d", "e",
"unknown."), class = "factor")), row.names = c(NA, -11L), class = "data.frame")
但是,对于我的数据,我最终使用 dput 得到了类似的结果,尽管我没有使用 data.table。
row.names = c(NA,
-5L), .internal.selfref = <pointer: 0x0000000004f81ef0>, class = c("data.table",
"data.frame"))
我正在尝试模仿我的数据,并在我尽快成功时将其摆出来。
【问题讨论】:
您的代码不可重现,因为我们没有Check
。尝试将其减小到仍能说明错误的更合理的大小,然后使用dput(Check)
将其包含在您的问题中。您还应该为您正在使用的每个软件包调用library()
。
@user2554330:感谢您的回复。我已经编辑了我的问题。我会在模仿成功后立即摆出“Check”。
由于错误发生在data.table
对象上,但似乎级别很低,也许它就像更新你的包(包括data.table
)一样简单,以便它们与你当前的 R 版本兼容。
我现在已经安装了 R 4.0.2(来自 R 4.0.1)并完全下载了所有的包和依赖项。它现在似乎工作了,但是,我又遇到了同样的麻烦。关闭一切并让它再次运行。而且,奇怪的是它没有任何麻烦。还是不明白问题出在哪里。
不,数据框自己不会做任何事情。如果该类包含"data.table"
,那是因为某些函数将其放在那里。在每次函数调用之前和之后检查类,你会找到罪魁祸首。
【参考方案1】:
下面的例子运行良好,没有任何问题:
library(tidyverse)
library(data.table)
Check <- data.frame(col1 = c(NA, letters[1:10]), col2 = c(NA, NA, 1:8, NA),
col3 = c(NA, letters[1:5], NA, NA, NA, NA, NA))
Test1 <- Check
dput(Test1)
Test2 <- as.data.table(Check) # Convert to data.table
dput(Test2)
Test1 <- droplevels(Test1)
str(Test1)
Test1 <- Test1 %>% dplyr::mutate_if(sapply(Test1, is.character), as.factor)
Test1 <- Test1 %>% dplyr::mutate_if(sapply(Test1, is.integer), as.numeric)
str(Test1)
Test1 <- droplevels(Test1)
Test2 <- droplevels(Test2)
str(Test2)
Test2 <- Test2 %>% dplyr::mutate_if(sapply(Test2, is.character), as.factor)
Test2 <- Test2 %>% dplyr::mutate_if(sapply(Test2, is.integer), as.numeric)
str(Test2)
Test2 <- droplevels(Test2)
现在考虑这个例子:
library(tidyverse)
library(data.table)
Check1 <- data.frame(col1 = c(NA, letters[1:200]), col2 = c(NA, NA, 1:198, NA),
col3 = c(NA, letters[1:195], NA, NA, NA, NA, NA),
col4 = c(NA, NA, letters[1:199]), col5 = c(NA, letters[7:206]),
col6 = c(NA, NA, letters[1:198], NA),
col7 = c(NA, letters[1:197], NA, NA, NA),
col8 = c(NA, letters[4:203]),
col9 = c(NA, letters[6:205]),
col10 = c(letters[1:200], NA),
col11 = c(NA, NA, letters[1:197], NA, NA),
col12 = c(NA, letters[2:201]),
col13 = c(NA, NA, NA, NA, NA, letters[1:196]) )
Check2 <- data.frame(replicate(100,sample(0:1000,201,rep=TRUE)))
Check <- cbind(Check1, Check2)
Test1 <- Check
dput(Test1)
# dput gives ,row.names = c(NA, -201L), class = "data.frame")
Test2 <- as.data.table(Check)
dput(Test2)
# dput gives row.names = c(NA, -201L), .internal.selfref = <pointer: 0x00000000052e1ef0>, class # = c("data.table", "data.frame"))
# The below block runs without any problem since Test1 is of class data.frame
Test1 <- droplevels(Test1)
str(Test1)
Test1 <- Test1 %>% dplyr::mutate_if(sapply(Test1, is.character), as.factor)
Test1 <- droplevels(Test1)
Test1 <- Test1 %>% dplyr::mutate_if(sapply(Test1, is.integer), as.numeric)
str(Test1)
Test1 <- droplevels(Test1)
# The below block gives problem since Test2 is of class = c("data.table", "data.frame")
Test2 <- droplevels(Test2)
str(Test2)
Test2 <- Test2 %>% dplyr::mutate_if(sapply(Test2, is.character), as.factor)
Test2 <- droplevels(Test2)
Test2 <- Test2 %>% dplyr::mutate_if(sapply(Test2, is.integer), as.numeric)
str(Test2)
Test2 <- droplevels(Test2)
我在运行前 4 行时收到以下错误消息:
Error in in .shallow(x, cols = cols, retain.key = TRUE) : can't set ALTREP truelength
如果我尝试打开 Test2 数据框,我会收到以下消息
View(Test2)
Error in View : can't set ALTREP truelength
但是,如果我使用删除 Test2
rm(Test2)
并运行以下命令,我没有收到任何错误:
Test2 <- as.data.frame(Test2)
str(Test2)
Test2 <- Test2 %>% dplyr::mutate_if(sapply(Test2, is.character), as.factor)
Test2 <- droplevels(Test2)
Test2 <- Test2 %>% dplyr::mutate_if(sapply(Test2, is.integer), as.numeric)
str(Test2)
Test2 <- droplevels(Test2)
大小限制是否在 data.table 中起作用,因为它似乎适用于小数据并且对上面的示例犹豫不决。
是不是每次都必须保证数据保存为class= "data.frame"的数据框?
这些数据框什么时候会自动转换为data.table,因为在我的真实数据集中虽然没有加载data.table库,但数据保存为data.table?
请解释一下?我有 R 4.0.2 并清理了空间并重新安装了所有软件包和依赖项,并且 RStudio 版本是 1.3.959 。
【讨论】:
很好的重现性。尝试使用 reprex() 并将其发布为问题以获得正确的关注:github.com/Rdatatable/data.table/issues以上是关于在新 R 版本中编译用旧版本编写的代码时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
在发布版本中使用英特尔 c++ 编译时出现“cin >> a >> b”编译错误
在 Windows 上编译时出现 Apache thrift 错误
在 R 中使用 RcppArmadillo 包和 rowvec 时出现编译错误
VS2017新建或拷贝项目编译时出现:找不到 Windows SDK 版本8.1.请安装所需的版本的 Windows SDK