在R/list中如何合并/rbind子 Dataframe

dddzy1tm  于 2023-07-31  发布在  其他
关注(0)|答案(3)|浏览(120)

有一个列表ori_list,如何合并子 Dataframe cat_a|cat_b合并到catitem_a|item_b合并到item?(结果就像new_list一样)

cat_a <- data.frame(name=c('A','B','C'),amount=c(1,2,3))
cat_b <- data.frame(name=c('w','B','C'),amount=c(4,2,3))
item_a <- data.frame(name=c('z','o','C'),amount=c(3,4,1))
item_b <- data.frame(name=c('n','B','C'),amount=c(6,6,3))

files <- ls(pattern = 'cat|item') %>% purrr::set_names()

ori_list <- list(mget(files))

new_list <- list(cat= data.frame(name = c('A','B','C','w','B','C'),
                            amount = c(1,2,3,4,2,3)),
                 item = data.frame(name=c('z','o','C','n','B','C'),
                                   amount=c(3,4,1,6,6,3)))

字符串

zpgglvta

zpgglvta1#

如果您熟悉tidyverse

ori_list_1[[1]] %>%  # (next line comment) combine all list. y is a list name and extract the chr before "_.
  purrr::imap_dfr(\(x, y) mutate(x, group_name = str_extract(y, "^.+(?=_)"))) %>% 
  split(.$group_name) %>%           # split by the group_name
  purrr::map(\(x) select(x, -group_name))  # delete group_name col.

字符串

k4aesqcs

k4aesqcs2#

试试这个。注意,你用错了mget,它已经产生了一个列表。

ori_list <- mget(files)

list(cat=do.call('rbind', ori_list[grep('^cat', names(ori_list))]),
     item=do.call('rbind', ori_list[grep('^item', names(ori_list))]))
# $cat
#         name amount
# cat_a.1    A      1
# cat_a.2    B      2
# cat_a.3    C      3
# cat_b.1    w      4
# cat_b.2    B      2
# cat_b.3    C      3
# 
# $item
#          name amount
# item_a.1    z      3
# item_a.2    o      4
# item_a.3    C      1
# item_b.1    n      6
# item_b.2    B      6
# item_b.3    C      3

字符串
你也可以

lapply(c('cat', 'item'), \(x) do.call('rbind', mget(ls(pattern=x, envir=.GlobalEnv), envir=.GlobalEnv))) |>
  setNames(c('cat', 'item'))
# $cat
#         name amount
# cat_a.1    A      1
# cat_a.2    B      2
# cat_a.3    C      3
# cat_b.1    w      4
# cat_b.2    B      2
# cat_b.3    C      3
# 
# $item
#          name amount
# item_a.1    z      3
# item_a.2    o      4
# item_a.3    C      1
# item_b.1    n      6
# item_b.2    B      6
# item_b.3    C      3


这样可能更好

m1m5dgzv

m1m5dgzv3#

你可以试试tapply + sub

tapply(
    mget(files),
    sub("_.*", "", files),
    \(x) {
        do.call(rbind, x)
    }
)

字符串
这给了

$cat
        name amount
cat_a.1    A      1
cat_a.2    B      2
cat_a.3    C      3
cat_b.1    w      4
cat_b.2    B      2
cat_b.3    C      3

$item
         name amount
item_a.1    z      3
item_a.2    o      4
item_a.3    C      1
item_b.1    n      6
item_b.2    B      6
item_b.3    C      3


如果你想要更干净的组合列表行名,你可以试试

tapply(
    mget(files),
    sub("_.*", "", files),
    \(x) {
        `row.names<-`(do.call(rbind, x), NULL)
    }
)


tapply(
    mget(files),
    sub("_.*", "", files),
    \(x) {
        Reduce(rbind, x)
    }
)


所以你会看到

$cat
  name amount
1    A      1
2    B      2
3    C      3
4    w      4
5    B      2
6    C      3

$item
  name amount
1    z      3
2    o      4
3    C      1
4    n      6
5    B      6
6    C      3

相关问题