首页 > 解决方案 > 在新 R 版本中编译用旧版本编写的代码时出现问题

问题描述

我在新版本的 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"))

我正在尝试模仿我的数据,并在我尽快成功时将其摆出来。

标签: rcompiler-errorsversion

解决方案


下面的示例运行良好,没有任何问题:

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)
  1. 大小限制是否在 data.table 中起作用,因为它似乎适用于小数据并且对上面的示例犹豫不决。

  2. 这是否意味着每次都必须确保将数据保存为class =“data.frame”的数据框?

  3. 这样的数据框什么时候会自动转换为data.table,因为在我的真实数据集中虽然没有加载data.table库,但数据被保存为data.table?

请问有什么解释吗?我有 R 4.0.2 并清理了空间并重新安装了所有软件包和依赖项,并且 RStudio 版本是 1.3.959 。


推荐阅读