如何将含列表列的DataFrame重塑为指定结构(R语言)
问题
现有如下结构的DataFrame,希望通过unnest操作将files列展开为以Files.为前缀的新列,得到指定的df2结构。当前尝试的代码无法实现目标,请问该如何操作?
原始代码
library(dplyr) library(tidyr) library(stringr) # 原代码用到str_c但未加载该包 df <- structure(list(url = "https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702", files = "list(sha = c(\"bca42f706ba9ef5b822cfc8581ca79bec93f28c2\", \"9f29ababe866e9d6df73bb730a0eb5d216562838\", \"3c3fe578da77c9d2dc92e339ecd4d954ed24ba15\", \"03f52efb0d0be91e580dd1d636b5fcc54033aacc\", \"6fd0a99f12295e0ce9ea56062ced4a92a7152470\", \"abfeef07a423b9fcae17e4a08de9a93f39448c25\", \"abfeef07a423b9fcae17e4a08de9a93f39448c25\", \"f98b02b85225bdf54206e1955aaa34ebe298899e\", \"d97d3cf93f85d48dd09dba15f7b0f652429980c3\"), filename = c(\"src/manifest.json\", \"src/skin/.DS_Store\", \"src/skin/dashboard.html\", \"src/skin/dist/main.dev.js\", \"src/skin/dist/welcome.dev.js\", \"src/skin/images/icon.png\", \"src/skin/images/icon2.png\", \"src/skin/main.js\", \"src/skin/welcome.html\"), status = c(\"modified\", \"modified\", \"modified\", \"removed\", \"removed\", \"modified\", \"removed\", \"modified\", \"modified\"), additions = c(8, 0, 0, 0, 0, 0, 0, 0, 4), deletions = c(8, 0, 1, 203, 142, 0, 0, 3, 3), changes = c(16, 0, 1, 203, 142, 0, 0, 3, 7))"), row.names = 1L, class = "data.frame") df_reshaped <- df %>% rename_all(funs(str_c("Files.", .))) %>% unnest(files)
期望结果
df2 <- data.frame(url = c("https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702", "https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702", "https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702", "https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702", "https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702", "https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702","https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702", "https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702","https://api.github.com/repos/aleecia/CCPABrowserTool/commits/fc795a994d6284633393ca940796ce82fd69f702"), Files.sha = c("bca42f706ba9ef5b822cfc8581ca79bec93f28c2", "9f29ababe866e9d6df73bb730a0eb5d216562838", "3c3fe578da77c9d2dc92e339ecd4d954ed24ba15", "03f52efb0d0be91e580dd1d636b5fcc54033aacc", "6fd0a99f12295e0ce9ea56062ced4a92a7152470", "abfeef07a423b9fcae17e4a08de9a93f39448c25", "abfeef07a423b9fcae17e4a08de9a93f39448c25", "f98b02b85225bdf54206e1955aaa34ebe298899e", "d97d3cf93f85d48dd09dba15f7b0f652429980c3"), Files.filename = c("src/manifest.json", "src/skin/.DS_Store", "src/skin/dashboard.html", "src/skin/dist/main.dev.js", "src/skin/dist/welcome.dev.js", "src/skin/images/icon.png", "src/skin/images/icon2.png", "src/skin/main.js", "src/skin/welcome.html"), Files.status = c("modified", "modified", "modified", "removed", "removed", "modified", "removed", "modified", "modified"), Files.additions = c(8, 0, 0, 0, 0, 0, 0, 0, 4), Files.deletions = c(8, 0, 1, 203, 142, 0, 0, 3, 3), Files.changes = c(16, 0, 1, 203, 142, 0, 0, 3, 7))
解决方案
你的代码存在两个核心问题:
files列是字符串格式,不是可直接展开的列表对象,unnest无法识别;- 提前用
rename_all给所有列加前缀,会导致url列也被重命名,不符合预期。
正确步骤如下:
- 先把
files列的字符串转换成实际的列表结构; - 展开
files列得到子列; - 给展开后的子列添加
Files.前缀,保留原url列不变。
完整实现代码:
library(dplyr) library(tidyr) library(stringr) df_reshaped <- df %>% # 将字符串格式的files转换为可操作的列表 mutate(files = lapply(files, function(x) eval(parse(text = x)))) %>% # 展开files列 unnest(files) %>% # 给除url外的所有列添加Files.前缀 rename_with(~str_c("Files.", .), -url)
运行后即可得到与df2结构一致的结果。
内容的提问来源于stack exchange,提问作者foc
相关产品推荐
相关产品推荐

