使用apply和gregexpr添加新列

时间:2018-02-14 11:17:03

标签: r

我有一个主列表,里面有几个包含许多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,但输出看起来不像我想要的那样。

我真的很感激这里的一些帮助。 提前谢谢。

致以最诚挚的问候,

2 个答案:

答案 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()