You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言如何对列表内多个数据框批量应用case_when函数转换列值

R列表批量处理数据框转换方案

首先先修正两处原有代码的问题:

  • 单数据框转换逻辑中FLOOR列的判断条件笔误:"FLOOR" == 1是字符串和数值比较,永远返回FALSE,需改为列名调用FLOOR == 1
  • 示例列表构建代码错误:as.list(df1, df2)无法生成包含两个数据框的列表,需改为sample_list <- list(df1, df2),同时不建议用sample做变量名,会和R内置的抽样函数sample()冲突。

方案1:base R + dplyr 实现(无额外依赖)

列表批量处理的核心逻辑是遍历列表内每个数据框元素,套用已经写好的mutate+case_when逻辑即可,用base R的lapply()就能实现:

library(dplyr)

# 构建正确的输入列表
df1 <- structure(list(FLOOR = c(1, 3, 3, 3, 3, 3), LIGHTING = c(1, 1, 1, 1, 4, 1), COOKING = c(3, 5, 5, 5, 5, 3), DRINKING_W = c(1,2, 2, 5, 7, 8), TOILET = c(1, 1, 1, 1, 1, 4), SEPTIC_TAN = c(1,2, 2, 3, 1, 0), TELEPHONE = c(2, 4, 4, 4, 4, 2), TENURE = c(1,1, 1, 4, 1, 1)), row.names = c(7L, 9L, 10L, 65L, 66L, 10578L), class = "data.frame")
df2 <- structure(list(FLOOR = c(3, 3, 3, 3, 6, 3), LIGHTING = c(1, 1,1, 1, 2, 1), COOKING = c(5, 5, 5, 5, 5, 5), DRINKING_W = c(7,7, 7, 7, 8, 8), TOILET = c(3, 3, 3, 3, 4, 4), SEPTIC_TAN = c(3,3, 3, 3, 0, 0), TELEPHONE = c(2, 2, 2, 2, 4, 2), TENURE = c(1,1, 1, 1, 2, 2)), row.names = 252098:252103, class = "data.frame")
sample_list <- list(df1, df2)

# 批量转换
processed_list <- lapply(sample_list, function(current_df) {
  current_df %>%
    mutate(FLOOR = case_when(FLOOR == 1 ~ "1", TRUE ~ "0"),
           LIGHTING = case_when(LIGHTING == 1 ~ "1", TRUE ~ "0"),
           COOKING = case_when(COOKING == 1 ~ "1", TRUE ~ "0"),
           DRINKING_W = case_when(DRINKING_W == 1 ~ "1", TRUE ~ "0"),
           TOILET = case_when(TOILET == 1 ~ "1", TRUE ~ "0"))
})

返回的processed_list和原列表顺序、结构完全一致,每个元素都是完成转换的数据框。


方案2:purrr 实现(适配tidyverse工作流)

如果你日常使用tidyverse生态的函数,用purrr::map()实现遍历语法更统一,逻辑和lapply完全一致:

library(dplyr)
library(purrr)

processed_list <- map(sample_list, ~.x %>%
                        mutate(FLOOR = case_when(FLOOR == 1 ~ "1", TRUE ~ "0"),
                               LIGHTING = case_when(LIGHTING == 1 ~ "1", TRUE ~ "0"),
                               COOKING = case_when(COOKING == 1 ~ "1", TRUE ~ "0"),
                               DRINKING_W = case_when(DRINKING_W == 1 ~ "1", TRUE ~ "0"),
                               TOILET = case_when(TOILET == 1 ~ "1", TRUE ~ "0")))

优化写法:消除重复代码

观察转换规则可以发现,5个目标列的判断逻辑完全相同:值等于1则返回字符串"1",否则返回"0",不需要重复写5次case_when,可以借助dplyr::across()一次性处理所有指定列,后续要增减转换列只需要修改目标列向量即可,维护成本更低:

# 把需要转换的列统一存在向量里
target_cols <- c("FLOOR", "LIGHTING", "COOKING", "DRINKING_W", "TOILET")

processed_list <- lapply(sample_list, function(current_df) {
  current_df %>%
    mutate(across(all_of(target_cols), ~case_when(.x == 1 ~ "1", TRUE ~ "0")))
})

如果你需要转换后的结果是数值型而非字符型,只需要去掉返回值的引号,写为~case_when(.x == 1 ~ 1, TRUE ~ 0)即可。


内容的提问来源于stack exchange,提问作者Kian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:51:17