在R中基于离散列生成4个带对应标识的新dataframe的方法
问题需求
输入DataFrame
isCool isTall isWide Building 1 0 0 1 0 2 1 1 0 1 3 1 0 1 2 4 0 1 0 3 5 1 0 0 1
Building列共有4个唯一值(0、1、2、3),需要输出4个新DataFrame,每个新增对应Building值的标识列:1表示该行属于对应Building,0表示不属于,每个输出DataFrame的行数和输入一致。
预期输出示例
对应Building 0的DF:
isCool isTall isWide Building_0 1 0 0 1 1 2 1 1 0 0 3 1 0 1 0 4 0 1 0 0 5 1 0 0 0
其余DF依次对应Building 1、2、3的标识规则。
现有实现问题
目前已经写了单标识生成函数,但需要手动调用4次生成所有目标DF,希望可以仅调用一次函数就生成全部结果:
flag_df <- function(df, colname, num) { df %>% mutate(colname = if_else(.data[[colname]] == num, 1, 0)) %>% rename_with(.fn = ~paste0(colname,"_", num),.cols = colname) %>% dplyr::select(-colname) } d_1 <- flag_df(test_df, "Building", 0) d_2 <- flag_df(test_df, "Building", 1) d_3 <- flag_df(test_df, "Building", 2) d_4 <- flag_df(test_df, "Building", 3)
解决方案
你可以通过遍历目标列的唯一值批量生成所有DF,既可以把结果存在列表里统一管理,也可以直接生成到全局环境直接调用,两种实现方式如下:
方式1:基于原有函数批量调用,结果存为列表
不用修改你现有的flag_df函数,直接遍历Building的唯一值即可:
# 获取Building列的所有唯一值 build_values <- unique(test_df$Building) # 批量调用生成所有DF,存为列表 df_list <- lapply(build_values, function(x) flag_df(test_df, "Building", x)) # 给列表按d_1、d_2的规则命名 names(df_list) <- paste0("d_", seq_along(df_list)) # 调用方式:要取Building 0对应的DF用df_list$d_1,Building 1对应df_list$d_2,以此类推
如果希望直接在工作环境生成d_1、d_2等独立变量,加上下面一行即可:
list2env(df_list, envir = .GlobalEnv)
方式2:封装为一次性调用的整合函数
也可以把逻辑整合为一个独立函数,直接调用一次就得到全部结果:
generate_all_flag_dfs <- function(df, target_col) { col_unique_vals <- sort(unique(df[[target_col]])) res <- lapply(col_unique_vals, function(val) { df %>% mutate("{target_col}_{val}" := as.integer(.data[[target_col]] == val)) %>% select(-all_of(target_col)) }) names(res) <- paste0("d_", seq_along(res)) # 取消下面一行的注释,即可直接在全局环境生成独立变量 # list2env(res, envir = .GlobalEnv) return(res) } # 仅需调用一次 all_result_dfs <- generate_all_flag_dfs(test_df, "Building")
内容的提问来源于stack exchange,提问作者Eisen
相关产品推荐
相关产品推荐

