R语言:如何拆分DataFrame并将拆分部分附加为新列?
解决按ID拆分DataFrame并横向拼接为新列的问题
我明白你的需求啦——你想要把按ID列拆分后的各个子DataFrame,横向拼接成一个包含所有列的宽表,而不是得到一个不好用的列表。咱们一步步来解决这个问题:
首先,先修正你原始代码里的一个小错误:你在处理日期的时候用了df$date,但实际列名是Date,先把这个改过来,避免报错。
方法一:基础R实现
# 原始数据 x <-c(1,2,3) y <-c(20200101,20200101,20200101) z <-c(4.5,5,7) x_name <- "ID" y_name <- "Date" z_name <- "value" df <-data.frame(x,y,z) names(df) <- c(x_name,y_name,z_name) # 修正日期格式处理(列名要对应) df$Date <- format(as.Date(as.character(df$Date), format="%Y%m%d")) # 按ID拆分得到列表 df_list <- split(df, f = df$ID) # 给每个子DataFrame的列名加上对应ID的后缀,避免列名重复 df_named_list <- lapply(names(df_list), function(id) { sub_df <- df_list[[id]] colnames(sub_df) <- paste0(colnames(sub_df), "_", id) sub_df }) # 横向拼接所有子DataFrame得到目标表 df_goal <- do.call(cbind, df_named_list)
方法二:tidyverse(dplyr+purrr)实现(更简洁)
如果你习惯用tidyverse工具包,这个方法会更直观:
library(tidyverse) # 原始数据(和上面一致) x <-c(1,2,3) y <-c(20200101,20200101,20200101) z <-c(4.5,5,7) x_name <- "ID" y_name <- "Date" z_name <- "value" df <-data.frame(x,y,z) names(df) <- c(x_name,y_name,z_name) # 处理日期+拆分+重命名列+横向拼接 df_goal <- df %>% mutate(Date = format(as.Date(as.character(Date), format="%Y%m%d"))) %>% group_split(ID) %>% # 按ID拆分 map2(names(.), ~rename_with(.x, ~paste0(.x, "_", .y))) %>% # 给列名加ID后缀 bind_cols() # 横向合并
最终结果
两种方法得到的df_goal结构和你想要的一致,列名会更清晰(比如ID_1、Date_1、value_1对应第一个ID的三列),内容如下:
ID_1 Date_1 value_1 ID_2 Date_2 value_2 ID_3 Date_3 value_3 1 1 2020-01-01 4.5 2 2020-01-01 5 3 2020-01-01 7
这样你就得到了一个结构清晰、易于使用的宽格式DataFrame啦!
内容的提问来源于stack exchange,提问作者Olli
相关产品推荐
相关产品推荐

