R中mutate结合paste0与paste的异常行为技术问询
为什么
mutate中paste0带collapse和paste的结果差异这么大? 嘿,这个问题其实是对paste()/paste0()的参数逻辑,以及dplyr::mutate()的执行规则理解不到位导致的,我给你拆解清楚:
1. 先看paste()的默认行为(不带collapse)
当你在mutate里用paste(as.character(wt), as.character(drat))时,paste()默认会逐行配对处理输入的向量:把每一行的wt字符和drat字符用默认分隔符(空格)拼接,生成一个和原数据行数完全一致的新向量。这完全符合mutate“给每一行生成对应新值”的预期,所以你看到的新列每一行都是该行两个值的拼接结果。
举个极简例子验证:
df <- tibble(wt = c(1.1, 2.2), drat = c(3.3, 4.4)) df %>% mutate(newcol = paste(wt, drat)) # 输出是每一行对应自己的拼接值: # # A tibble: 2 × 3 # wt drat newcol # <dbl> <dbl> <chr> # 1 1.1 3.3 "1.1 3.3" # 2 2.2 4.4 "2.2 4.4"
2. paste0(..., collapse=";")的“异常”根源
当你给paste0()加上collapse参数后,逻辑就完全变了:
- 第一步:
paste0先按位置逐行拼接wt和drat的字符(因为paste0默认sep="",所以直接连在一起),得到一个临时的向量,比如上面的例子会得到["1.13.3", "2.24.4"]; - 第二步:
collapse=";"会把这个临时向量的所有元素拼成一个单一的大字符串,也就是"1.13.3;2.24.4"; - 第三步:
mutate拿到这个单一字符串后,会把它重复填充到新列的每一行里——因为它只收到了一个值,所以整个新列都是同一个大字符串。
同样用例子看:
df %>% mutate(newcol = paste0(as.character(wt), as.character(drat), collapse=";")) # 输出的新列全是同一个拼接后的大字符串: # # A tibble: 2 × 3 # wt drat newcol # <dbl> <dbl> <chr> # 1 1.1 3.3 "1.13.3;2.24.4" # 2 2.2 4.4 "1.13.3;2.24.4"
3. 如果你想实现逐行用paste0拼接怎么办?
很简单,去掉collapse参数就行!直接用paste0(as.character(wt), as.character(drat)),它会和paste(as.character(wt), as.character(drat), sep="")效果完全一致,逐行生成对应拼接值,符合你对mutate的预期。
内容的提问来源于stack exchange,提问作者Liang
相关产品推荐
相关产品推荐

