R语言:基于猫名字首字母自动生成对应数字列的更优实现方法咨询
R语言:基于猫名字首字母自动生成对应数字列的更优实现方法咨询
嗨,Jane!你现在用case_when()手动匹配每个字母的思路是可行的,但要是要覆盖A到Z所有26个字母,手动写26条判断肯定特别麻烦。这里有几个更简洁高效的方法,能帮你自动完成这个需求:
方法一:Base R 原生实现(无需额外加载包)
这种方法不用依赖第三方工具,用R原生函数就能轻松搞定:
方案1:利用ASCII码转换
大写字母A的ASCII码是65,B是66,以此类推。我们先提取每个猫名的首字母并转成大写,再通过ASCII码计算对应数字(减去65再加1就能得到1、2、3...的对应值):
df <- data.frame(catname=c("Ave", "Ares", "Aze", "Bill", "Buz", "Chris", "Chase", "Charlie", "Coco")) df$firstletter <- utf8ToInt(toupper(substr(df$catname, 1, 1))) - utf8ToInt("A") + 1
方案2:用match()匹配内置字母序列
R里有现成的大写字母序列LETTERS,我们可以用match()函数把首字母和这个序列做匹配,返回的位置就是对应的数字:
df$firstletter <- match(toupper(substr(df$catname, 1, 1)), LETTERS)
方法二:Tidyverse 风格实现
如果你习惯用dplyr和stringr的管道流操作,也可以写成更贴合tidy数据习惯的形式:
library(dplyr) library(stringr) df <- df %>% mutate( # 提取首字母并转大写,避免小写字母干扰 first_letter = str_to_upper(str_sub(catname, 1, 1)), # 把字母转成因子再转整数(因子水平默认按LETTERS顺序排列) firstletter = as.integer(factor(first_letter, levels = LETTERS)) ) %>% select(-first_letter) # 移除中间临时生成的列
要是想更精简,还能把两步合并成一行:
df <- df %>% mutate(firstletter = match(str_to_upper(str_sub(catname, 1, 1)), LETTERS))
验证结果
运行上面任意一种方法后,你的数据框都会得到预期的结果:
| catname | firstletter |
|---|---|
| Ave | 1 |
| Ares | 1 |
| Aze | 1 |
| Bill | 2 |
| Buz | 2 |
| Chris | 3 |
| Chase | 3 |
| Charlie | 3 |
| Coco | 3 |
另外提个小细节:你原来的代码里用了str_start(),其实stringr包里的正确函数是str_starts(),不过用上面的方法就完全不需要写这些重复判断啦~
备注:内容来源于stack exchange,提问作者Jane
相关产品推荐
相关产品推荐

