R中给数据框列表添加文件名列时ifelse函数不生效问题排查
问题原因与解决办法
核心原因
你写的ifelse语句只计算了修改后的值,但没有将结果赋值回原数据框的Plot列,等于白运行了这个函数,自然看不到修改效果。比如你写的ifelse(files[[i]]$Plot == "alhamilla.csv", files[[i]]$Plot == "alhamilla", files[[i]]$Plot),只是返回了一个新的向量,但没把这个向量存到files[[i]]$Plot里,原数据框完全没变化。
另外,你用固定长度的str_sub提取文件名的方式很容易出错(比如文件路径长度变化时就会提取错误),建议用basename()+tools::file_path_sans_ext()来准确提取不带路径和后缀的文件名。
修正你的原有代码
把每个ifelse的结果赋值回files[[i]]$Plot即可:
##Correct the names for( i in seq_along(files)){ files[[i]]$Plot <- ifelse(files[[i]]$Plot == "alhamilla.csv", "alhamilla", files[[i]]$Plot) files[[i]]$Plot <- ifelse(files[[i]]$Plot == "/test/amo.csv", "amoladeras", files[[i]]$Plot) files[[i]]$Plot <- ifelse(files[[i]]$Plot == "est/falto.csv", "falto", files[[i]]$Plot) files[[i]]$Plot <- ifelse(files[[i]]$Plot == "est/fbajo", "fbajo", files[[i]]$Plot) files[[i]]$Plot <- ifelse(files[[i]]$Plot == "st/fmedio.csv", "fmedio", files[[i]]$Plot) files[[i]]$Plot <- ifelse(files[[i]]$Plot == "/test/G1.csv", "G1", files[[i]]$Plot) files[[i]]$Plot <- ifelse(files[[i]]$Plot == "/test/G2.csv", "G2", files[[i]]$Plot) files[[i]]$Plot <- ifelse(files[[i]]$Plot == "/test/G3.csv", "G3", files[[i]]$Plot) }
更高效的写法(推荐)
用映射表批量替换,同时优化文件名提取步骤,避免循环里重复判断:
# 读取文件路径 filesinfolder <- list.files("C:/test", pattern="*.csv", full.names=TRUE) # 提取纯文件名(去掉路径和.csv后缀) raw_names <- tools::file_path_sans_ext(basename(filesinfolder)) # 构建文件名映射表:原始名 -> 目标名 name_mapping <- c( "amo" = "amoladeras", "alhamilla" = "alhamilla", "falto" = "falto", "fbajo" = "fbajo", "fmedio" = "fmedio", "G1" = "G1", "G2" = "G2", "G3" = "G3" ) # 读取文件并添加Plot列 files <- lapply(seq_along(filesinfolder), function(i) { df <- read.csv(filesinfolder[i], sep = ",") # 用映射表替换,没有匹配的就用原始名 df$Plot <- name_mapping[raw_names[i]] %||% raw_names[i] df })
如果习惯用tidyverse工具,代码会更简洁:
library(purrr) library(dplyr) filesinfolder <- list.files("C:/test", pattern="*.csv", full.names=TRUE) raw_names <- tools::file_path_sans_ext(basename(filesinfolder)) name_mapping <- c( "amo" = "amoladeras", "alhamilla" = "alhamilla", "falto" = "falto", "fbajo" = "fbajo", "fmedio" = "fmedio", "G1" = "G1", "G2" = "G2", "G3" = "G3" ) files <- map2(filesinfolder, raw_names, ~{ read.csv(.x, sep = ",") %>% mutate(Plot = name_mapping[.y] %||% .y) })
内容的提问来源于stack exchange,提问作者Borja R
相关产品推荐
相关产品推荐

