在避免循环的同时更改/强制tibble的多个列

时间:2018-06-12 10:17:37

标签: r tibble

我有几个列,其中数字存储为文本:

my_tbl <- tibble(names = letters[1:5],
                 value1 = as.character(runif(5)), 
                 value2 = as.character(runif(5)))

现在,我想将这些列的类型(“value1”和“value2”)从字符更改为数字。只有我发现的选项是使用for循环:

for (i in 2:ncol(my_tbl)) {
  my_tbl[[i]] <- as.numeric(my_tbl[[i]])
}

是否有可能在没有循环的情况下执行此操作?

2 个答案:

答案 0 :(得分:3)

您可以使用mutate_if中的dplyr

library(dplyr)

my_tbl %>% 
  group_by(names) %>% 
  mutate_if(is.character, as.numeric)


my_tbl 
## A tibble: 5 x 3
## Groups:   names [5]
#  names value1 value2
#  <chr>  <dbl>  <dbl>
#1 a      0.427 0.0191
#2 b      0.817 0.300 
#3 c      0.108 0.158 
#4 d      0.394 0.643 
#5 e      0.775 0.311 

答案 1 :(得分:2)

使用purrr,你可以这样做:

如果您已经知道目标列:

library(purrr)
modify_at(my_tbl,-1,as.numeric)

如果您需要检测它们:

modify_if(my_tbl,~is.character(.) && !any(grepl("[:alpha:]",.)),as.numeric)

# # A tibble: 5 x 3
#   names value1 value2
#  <chr>  <dbl>  <dbl>
# 1 a      0.715 0.943 
# 2 b      0.639 0.128 
# 3 c      0.471 0.0395
# 4 d      0.374 0.374 
# 5 e      0.500 0.800 

使用dplyr代替purrr,这些将产生相同的结果:

library(dplyr)
mutate_at(my_tbl,-1,as.numeric)
mutate_if(my_tbl,~is.character(.) && !any(grepl("[:alpha:]",.)),as.numeric)

基础R翻译:

my_tbl[-1] <- lapply(my_tbl[-1],as.numeric)
my_tbl[] <- lapply(my_tbl,function(x)
  if (is.character(x) && !any(grepl("[:alpha:]",x))) as.numeric(x)
  else x)