R语言中数字转字符出现多余前导空格的原因咨询
问题:重复调用apply处理tibble后生成的列出现多余前导空格
以下是最小可复现代例:
df <- tibble::tibble( x=c(1, 10) ) mwe <- function(row) { return(paste0(row[["x"]])) } df$mwe1 = apply(df, 1, mwe) df$mwe2 = apply(df, 1, mwe)
实际运行后df的结果:
# A tibble: 2 × 3 x mwe1 mwe2 <dbl> <chr> <chr> 1 1 1 " 1" 2 10 10 "10"
预期结果应为:
# A tibble: 2 × 3 x mwe1 mwe2 <dbl> <chr> <chr> 1 1 1 1 2 10 10 10
原因分析
问题出在apply函数的底层行为:当对tibble调用apply(..., 1, ...)时,apply会先把tibble转换为矩阵。矩阵要求所有元素类型一致,第一次调用apply后,df新增了字符型列mwe1,此时df的列同时包含数值型和字符型;第二次调用apply时,转换后的矩阵会把所有元素统一转为字符型,并且为了对齐列宽,数值1会被补上前导空格(因为10是两位字符宽度),最终返回的就是带空格的字符串,tibble显示这类字符串时会自动加上引号,以区分普通字符串和带空格的字符串。
解决方法
避免用apply处理tibble,改用专为数据框/tibble设计的逐行处理工具:
- 使用
dplyr的rowwise:
library(dplyr) df <- tibble::tibble(x = c(1, 10)) %>% rowwise() %>% mutate( mwe1 = paste0(x), mwe2 = paste0(x) ) %>% ungroup()
- 使用
purrr的map_chr:
library(purrr) df <- tibble::tibble(x = c(1, 10)) df$mwe1 <- map_chr(df$x, paste0) df$mwe2 <- map_chr(df$x, paste0)
这两种方式都不会将数据转换为矩阵,而是直接逐个处理元素,因此不会出现前导空格问题。
内容的提问来源于stack exchange,提问作者Raniere Silva
相关产品推荐
相关产品推荐

