乐于分享
好东西不私藏

我花三天试了三个AI帮我写R代码:一个细节一塌糊涂;一个……总之不敢用了

我花三天试了三个AI帮我写R代码:一个细节一塌糊涂;一个……总之不敢用了

事情是这样的。

上个月我做数据分析,需要处理一份有点恶心的问卷数据——列名是中文,值有的是数字有的是文本,还有大量空值。我实在不想自己一行行写 dplyr 清洗代码,于是决定:让AI来写。

我选了三个AI:ChatGPT、某国产免费模型(代号M)、以及Claude。每个给同样的任务,各用一天。

三天后,我差点把电脑砸了——不是气的,是怕的。

第一天:国产免费模型M——代码不完全错,但细节一塌糊涂

我先拿免费模型M开刀,反正不要钱,试试呗。

我把需求贴进去:

我有一个CSV文件,列名是“年龄”“收入”“城市”,需要: 1)删除年龄<18的行; 2)把收入列的空值填充为中位数; 3)把城市列里的“北京”“上海”“广州”统一成“一线”,其他改成“其他”。

它秒回了一段R代码:

ounter(lineounter(lineounter(lineounter(linedf <- read.csv("data.csv")df <- df[df$年龄 >= 18, ]df$收入[is.na(df$收入)] <- median(df$收入, na.rm = TRUE)df$城市 <- ifelse(df$城市 %in% c("北京","上海","广州"), "一线""其他")

乍一看没问题,我复制、运行——

报错:

ounter(lineError: unexpected input in 'df$年龄'

问题出在非标准列名。在R里,包含中文或特殊字符的列名,最好用反引号包起来:df$`年龄`

但更坑的是,我的CSV是 UTF-8-BOM 格式,read.csv() 读取后,列名前可能带有隐藏字符,导致 $年龄 无法正确匹配。

M的代码框架没错,但完全忽略了真实数据环境中的编码和列名问题

你说它错吧,也不是;但你要真用它,会被坑到怀疑人生

我给它的评价是:👉 “只会写示例代码,不会处理真实数据。”

第二天:ChatGPT——能跑,但默认“帮你做决定”

第二天我换了ChatGPT(GPT-4o)。我特地补充了一句:

注意中文列名处理

它给出的代码是这样的:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linelibrary(dplyr)library(readr)df <- read_csv("data.csv")df <- df %>%  filter(`年龄` >= 18%>%  mutate(    `收入` = if_else(is.na(`收入`), median(`收入`, na.rm = TRUE), `收入`),    `城市` = case_when(      `城市` %in% c("北京""上海""广州"~ "一线",      TRUE ~ "其他"    )  )

这次我一跑——完全正常。

但问题也随之出现。

⚠️ 问题1:它“默认帮你做了不可逆操作”

case_when() 里的 TRUE ~ "其他",意味着所有非一线城市都被覆盖成“其他”。在当前需求下没错,但它没有提醒这是覆盖操作,也没有保留原始列。

更稳的写法应该是新建一列:

ounter(linedf$城市_分类 <- ifelse(df$城市 %in% c("北京","上海","广州"), "一线""其他")

⚠️ 问题2:代码“过度工程化”

它用了 read_csv()if_else()case_when(),这些都没错,但对简单任务来说有点“用力过猛”。新手容易看不懂、不敢改、一改就崩。

ChatGPT的问题不是写错,而是:👉 默认你是一个“会二次开发的人”

我最后改成了更直观的版本:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linedf <- read.csv("data.csv", fileEncoding = "UTF-8-BOM", check.names = FALSE)df <- df[df$`年龄` >= 18, ]median_income <- median(df$`收入`, na.rm = TRUE)df$`收入`[is.na(df$`收入`)] <- median_incomedf$城市_分类 <- ifelse(df$`城市` %in% c("北京","上海","广州"), "一线""其他")

更长,但——我敢改、敢查、敢debug。

第三天:Claude——最像“靠谱同事”的AI

第三天我试了Claude(Sonnet 3.5)。

它给的代码是:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linedf <- read.csv("data.csv", fileEncoding = "UTF-8-BOM", check.names = FALSE)# 过滤年龄df <- df[df$`年龄` >= 18, ]# 填充收入缺失值median_income <- median(df$`收入`, na.rm = TRUE)df$`收入`[is.na(df$`收入`)] <- median_income# 城市分类(保留原字段)df$城市_分类 <- ifelse(df$`城市` %in% c("北京","上海","广州"), "一线""其他")

没有炫技,没有复杂函数,但:

  • 每一步都可读
  • 每一步都可改
  • 默认保留原数据

更关键的是,它额外提醒了一句:

建议检查年龄列是否存在异常值(如负数或大于120)

这一下就从“写代码”,变成了“懂数据”。

后来我又加了一个需求:

把收入分成低、中、高三档(按分位数)

它给出的代码:

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(linedf$收入等级 <- cut(  df$`收入`,  breaks = quantile(df$`收入`, probs = c(0, 1/3, 2/3, 1), na.rm = TRUE),  labels = c("低""中""高"),  include.lowest = TRUE)

一次通过。

那天下午我很兴奋,但晚上冷静下来,有点后怕:

  • 如果我一直依赖它,我还会debug吗?
  • 如果它哪天不能用了,我还能独立写吗?
  • 我现在的能力,到底是“我会”,还是“我会问”?

三天总结

  • 免费模型M:能写结构,但不懂真实数据环境(编码、脏数据、列名问题)。
  • ChatGPT:能写对,但默认你是进阶用户(代码偏复杂、隐含决策多)。
  • Claude:最接近“有经验的同事”(稳、清晰、考虑数据问题)。

最后我的结论

我还是回去自己写代码了。

不是AI不行,而是:有些能力,必须长在自己身上。

AI可以帮你写代码、提供思路、快速试错。但它不能帮你理解数据、判断异常、建立数据直觉。

它更像是——一个放大器你本来会一点,它让你更快;但如果你完全不会,它只会让你“看起来会”。

一句话总结:AI是拐杖,不是腿。

互动

你平时写代码最常用哪个AI?翻过最离谱的车是什么?

点个关注,下回见。