Ошибка R data.table не может переименовывать имена столбцов, которые являются NA
У меня есть таблица data.table, где имена столбцов NA
. попытка сменить их на имя персонажа не удалась, и они остаются NA
.
Мне удается заменить их, переключившись на data.frame, но есть ли способ с data.table
?
dt <- data.table(a = 1:2, b = 2:3)
setDF(dt)
names(dt) <- c(NA,"c")
setDT(dt)
names(dt) <- c("a","b")
names(dt)
# [1] NA "b"`
Использование data.frame работает:
setDF(dt)
names(dt) <- c("a", "b")
names(dt)
# [1] "a" "b"`
EDIT:
@akrun предлагает использовать NA_character_, но это не работает для нескольких NA в именах (это мой случай, но приведенный выше пример был упрощен)
dt <- data.table(a = 1:2, b = 2:3, c = 2:3)
setDF(dt)
names(dt) <- c(NA,NA,"c")
setDT(dt)
setnames(dt, NA_character_, c('a','b'))
Ошибка в setnames(dt, NA_character_, c("a", "b"))
: Некоторые элементы old
дублируются (неоднозначны) в именах столбцов: NA
setnames(dt, c(NA_character_,NA_character_), c('a','b'))
Ошибка в setnames(dt, c(NA_character_, NA_character_), c("a", "b"))
: Некоторые дубликаты существуют в old
: NA
PS:
sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-suse-linux-gnu (64-bit)
Running under: SUSE Linux Enterprise Desktop 12 SP2
Matrix products: default
BLAS/LAPACK: /usr/lib64/libopenblas_serial.so.0
locale:
[1] LC_CTYPE=en_GB.UTF-8 LC_NUMERIC=C LC_TIME=en_GB.UTF-8
[4] LC_COLLATE=en_GB.UTF-8 LC_MONETARY=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8
[7] LC_PAPER=en_GB.UTF-8 LC_NAME=C LC_ADDRESS=C
[10] LC_TELEPHONE=C LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] parallel stats graphics grDevices utils datasets methods base
other attached packages:
[1] rvest_0.3.2 xml2_1.1.9000 bindrcpp_0.2 shiny_1.0.5
[5] dplyr_0.7.3 RUnit_0.4.31 gjpoisson_0.4
[17] gplots_3.0.1 moments_0.14 foreach_1.4.3 ggplot2_2.2.1
[21] RODBC_1.3-15 data.table_1.10.4-3 mgcv_1.8-21 nlme_3.1-131
[25] pacman_0.4.6 devtools_1.13.3
loaded via a namespace (and not attached):
[1] bitops_1.0-6 xts_0.10-0 lubridate_1.6.0 bit64_0.9-7
[5] httr_1.3.1 quantDb_0.4.0 RColorBrewer_1.1-2 tools_3.4.2
[9] backports_1.1.1 rredis_1.7.0 R6_2.2.2
[13] KernSmooth_2.23-15 rpart_4.1-11 Hmisc_4.0-3 DBI_0.7
[17] lazyeval_0.2.0 colorspace_1.3-2 nnet_7.3-12 withr_2.0.0
[21] gridExtra_2.3 curl_2.8.1 bit_1.1-12 compiler_3.4.2
[25] htmlTable_1.9 caTools_1.17.1 scales_0.5.0 dygraphs_1.1.1.4
[29] checkmate_1.8.3 odbc_1.1.1 speedglm_0.3-2 stringr_1.2.0
[33] digest_0.6.12 foreign_0.8-69 datashop_0.13.2 base64enc_0.1-3
[37] pkgconfig_2.0.1 htmltools_0.3.6 htmlwidgets_0.9 rlang_0.1.2
[41] ggthemes_3.4.0 bindr_0.1 zoo_1.8-0 gtools_3.5.0
[45] acepack_1.4.1 inline_0.3.14 marketUtils_0.3.8 magrittr_1.5
[49] Formula_1.2-2 Matrix_1.2-11 Rcpp_0.12.12 munsell_0.4.3
[53] stringi_1.1.5 yaml_2.1.14 MASS_7.3-47 RJSONIO_1.3-0
[57] plyr_1.8.4 grid_3.4.2 blob_1.1.0 gdata_2.18.0
[61] ggrepel_0.6.5 lattice_0.20-35 splines_3.4.2 fasttime_1.0-2
[65] hms_0.3 knitr_1.17 reshape2_1.4.2 codetools_0.2-15
[69] fctsUtils_0.4.7 XML_3.98-1.9 glue_1.1.1 latticeExtra_0.6-28
[73] selectr_0.3-1 httpuv_1.3.5 gtable_0.2.0 purrr_0.2.4
[77] tidyr_0.7.1 assertthat_0.2.0 mime_0.5 xtable_1.8-2
[81] survival_2.41-3 quantum_0.13.1 tibble_1.3.4 iterators_1.0.8
[85] memoise_1.1.0 cluster_2.0.6
>
Ответы
Ответ 1
Это была ошибка, спасибо за выявление проблемы и предоставление воспроизводимого примера! Вы должны иметь возможность установить текущую версию разработки data.table
(1.10.5) с помощью:
install.packages('data.table', type = 'source',
repos = 'http://Rdatatable.github.io/data.table')
Если это не работает напрямую, обратитесь к Installation Wiki.
Если вы не можете установить эту версию (права администратора или установить только из CRAN), здесь обходной путь: ошибка возникает, когда присутствует только аргумент old
setnames
(в этом случае он несколько парадоксально - хотя я думаю, что интуитивно в использовании - интерпретируется как new
).
Итак, чтобы обойти это, нам нужно только обязательно использовать аргументы old
и new
для setnames
:
setnames(dt, seq_along(dt), c('a', 'b', 'c'))
dt
# a b c
# 1: 1 2 2
# 2: 2 3 3
Мы не можем использовать names(dt)
в аргументе old
, потому что в names(dt)
есть дубликаты, а когда old
- character
, мы должны иметь возможность сопоставить 1-1 old
и new
(т.е. a
принадлежит первому NA
или второму? Эта же проблема возникла бы, если names(dt)
был c('a', 'a', 'b')
для запуска (т.е. отдельной проблемы). вокруг этого мы указываем позиции вместо имен.