我有一个主列表,里面有几个包含许多data.frames的子列表。 见下面的例子:
sublist1 <- list(data.frame('Position' = c(1,2,3), 'Color' = c("black-white-
silver-red","black-white-red","black-white")),
data.frame('Position' = c(1,2,3), 'Color' = c("black-white-
pink-gold-red","black-white","black")) )
sublist2 <- list(data.frame('Position' = c(1,2,3), 'Color' = c("black-
silver-red","black-white-red","white")),
data.frame('Position' = c(1,2,3), 'Color' = c("pink-gold-
red","black-white","black-white")) )
mainList <- list(sublist1, sublist2)
我正在尝试为每个data.frame添加一个名为'Color_Count'的新列,它将返回data.frame每行的不同颜色数。理想情况下,输出看起来像这样:
> mainList
[[1]]
[[1]][[1]]
Position Color Color_Count
1 1 black-white-silver-red 4
2 2 black-white-red 3
3 3 black-white 2
[[1]][[2]]
Position Color Color_Count
1 1 black-white-pink-gold-red 5
2 2 black-white 2
3 3 black 1
....
我尝试过使用gregexpr函数以及lapply,但输出看起来不像我想要的那样。
我真的很感激这里的一些帮助。 提前谢谢。
致以最诚挚的问候,
答案 0 :(得分:6)
如果我们可以假设每种颜色用短划线“ - ”分隔,我们可以简单地计算颜色列中的短划线数并添加1:
foo <- function(lst, col) {
lapply(lst, function(x)
if(!is.data.frame(x)) foo(x, col)
else transform(x, ColorCount = stringr::str_count(x[[col]], "-")+1))}
foo(mainList, "Color")
#[[1]]
#[[1]][[1]]
# Position Color ColorCount
#1 1 black-white-\nsilver-red 4
#2 2 black-white-red 3
#3 3 black-white 2
#
#[[1]][[2]]
# Position Color ColorCount
#1 1 black-white-pink-gold-red 5
#2 2 black-white 2
#3 3 black 1
#...
我正在使用stringr
库来计算计数,但您也可以使用基本R或stringi或其他方法。
我已经将foo
构建为递归函数,因为你有一个列表列表,我们只想处理最里面列表中的data.frames。
答案 1 :(得分:0)
替代方法:将嵌套列表提取到单个整洁的数据框
此方法需要来自名为data.table
的{{1}}包和rbindlist()
包
dplyr
我发现df <- lapply(mainList, rbindlist, idcol = "sub.id") %>%
rbindlist(idcol = "id") %>%
mutate(
Color = stringi::stri_replace_all(Color, "", regex = "\\n|\\s"),
Color_Count = stringi::stri_count(Color, regex = "-") + 1
)
的优点在于它允许您在取消嵌套数据帧时指定ID。
输出应如下所示:
rbindlist()