R 当绑定来自不同数据帧的行时,如何维护原始行名称?
使用dply::Summary时,如何保留其中一个分组名称?或者,有没有更好的方法来保留其中一个组名?我可能做这件事效率很低 我有一个data.frame(df)如下: 定义 其中,AU是由五(5)个“组”组成的集合,BU是由五十五(55)个单元组成的集合,所有这些单元都属于五个AU中的一个。亲子关系。分数是一个原始数字0-4。Control_Category是一个有六个(字符串值)的变量 目前,我的代码被分解成这样,脚本执行两个级别的分组和分数聚合,以给出简单的平均值。我首先在AU级别分组,以获得给定组中所有单元各自类别(CC)的简单平均值。最后,我有五个data.frames(cbg.au.stat.wide、cbd.au.stat.wide等)。这些dfs表示给定组的所有单元中给定类别的平均分数R 当绑定来自不同数据帧的行时,如何维护原始行名称?,r,dplyr,rows,R,Dplyr,Rows,使用dply::Summary时,如何保留其中一个分组名称?或者,有没有更好的方法来保留其中一个组名?我可能做这件事效率很低 我有一个data.frame(df)如下: 定义 其中,AU是由五(5)个“组”组成的集合,BU是由五十五(55)个单元组成的集合,所有这些单元都属于五个AU中的一个。亲子关系。分数是一个原始数字0-4。Control_Category是一个有六个(字符串值)的变量 目前,我的代码被分解成这样,脚本执行两个级别的分组和分数聚合,以给出简单的平均值。我首先在AU级别分组,以
# Group1 assessment unit scores
cbg.au.stat.wide <- df %>%
group_by(AU, CC) %>%
filter(AU == "CBG") %>%
summarise(avg = mean(Score, na.rm = TRUE)) %>%
dcast(AU ~ CC, value.var = "avg") %>%
print() # end chain
稍后,所有“AU级别”数据帧都使用dplyr::bind_行进行组合
au.avg.scores <- bind_rows(
bsa.au.stat.wide,bsg.au.stat.wide,cbd.au.stat.wide,
cbg.au.stat.wide,wmg.au.stat.wide)
au.avg.scores
AU AUDIT CORC GOV PPS TMSC TRAIN
1 BSA Admin 2.833333 2.000000 2.733333 2.000000 1.750000 2.333333
2 BSG 2.833333 0.000000 2.733333 2.000000 1.750000 2.333333
3 CBD 1.833333 2.533333 2.466667 2.000000 2.500000 2.166667
4 CBG 3.000000 2.733333 2.200000 2.666667 1.583333 2.666667
5 WMG 2.625000 1.816667 2.533333 2.166667 1.895833 2.375000
我想你会注意到,在“BU”级别上,“AU”级别已经降低。最后,我想将所有这些总线组合成一个大表,显示BU和AU的起源
这样它就会变成这样:
> bu.avg.scores
AU BU AUDIT CORC GOV PPS TMSC TRAIN
CBG Adherence 3.0 1.4 3.2 1 1.50 3.0
CBG CTR 2.0 2.8 2.0 4 1.50 2.5
CBG HRCU 3.5 1.8 3.0 1 2.25 1.5
CBD Investigations 2.0 NA NA NA NA NA
BSG ACH 2.0 0.0 2.0 4 1.50 2.5
最新答案
下面是一个基于评论线索的更新答案。我们分别通过AU
和BU
进行总结,并将结果存储在列表中。然后,我们将展示如何将摘要组合到单个数据帧中,并将摘要输出为表
library(tidyverse)
# Summarize by AU and (separately) by BU and store each summary in a list
dfs = list(AU = df %>%
group_by(AU, CC) %>%
summarise(avg=mean(Score, na.rm=TRUE)),
BU = df %>%
group_by(BU, CC) %>%
summarise(avg=mean(Score, na.rm=TRUE)))
每个摘要现在都存储在单独的列表元素中。这使两个不同级别的摘要保持分离,但存储在一个对象中,因此便于进一步处理
dfs
如果需要单个数据帧,可以执行以下操作:
# Combine into a single table and spread
df.table = bind_rows(dfs, .id="Unit Level") %>%
replace(., is.na(.), "") %>% # To avoid "NA" values when we "unite" below
unite(Unit, AU, BU, sep="") %>%
spread(CC, avg)
df.table
```{r, results="asis"}
library(xtable)
options(xtable.include.rownames=FALSE, xtable.comment=FALSE)
print(xtable(df.table %>%
mutate(`Unit Level` = replace(`Unit Level`, duplicated(`Unit Level`), ""))),
hline.after=c(-1,0,cumsum(table(df.table["Unit Level"]))))
```
如果要在r标记中创建报告
,可以将其转换为输出表。下面是我们删除重复行标识符的示例:
```{r}
knitr::kable(df.table %>%
mutate(`Unit Level` = replace(`Unit Level`, duplicated(`Unit Level`), "")))
```
这是在PDF文件中输出时表格的外观:
或者,如果您想添加一条中间线来分隔AU
和BU
平均值,您可以这样做:
# Combine into a single table and spread
df.table = bind_rows(dfs, .id="Unit Level") %>%
replace(., is.na(.), "") %>% # To avoid "NA" values when we "unite" below
unite(Unit, AU, BU, sep="") %>%
spread(CC, avg)
df.table
```{r, results="asis"}
library(xtable)
options(xtable.include.rownames=FALSE, xtable.comment=FALSE)
print(xtable(df.table %>%
mutate(`Unit Level` = replace(`Unit Level`, duplicated(`Unit Level`), ""))),
hline.after=c(-1,0,cumsum(table(df.table["Unit Level"]))))
```
原始答案
在下面的代码中,我们首先计算AU
和BU
级别的平均值。然后,我们计算AU
级别的平均值,并使用bind_rows
组合两个级别的平均值。然后我们可以将生成的数据帧扩展为宽格式
library(tidyverse)
# Get averages at the AU-BU level
dfs = df %>%
group_by(AU, BU, CC) %>%
summarise(avg = mean(Score, na.rm = TRUE))
dfs
这可以组合成一条链:
dfs = df %>%
group_by(AU, BU, CC) %>%
summarise(avg = mean(Score, na.rm = TRUE)) %>%
bind_rows(
df %>%
group_by(AU, CC) %>%
summarise(avg = mean(Score, na.rm = TRUE)) %>%
mutate(BU = paste("All", AU,"BU"))
) %>%
spread(CC, avg)
我需要展示两个结果:非盟级别的类别平均值(其中有五个)和BU级别的类别平均值(总共有55个)。如果您显示的“所有CBD”是AU级别的平均值,而基础行是BU级别的平均值,那么我认为这是合适的!当你说“结合两个平均水平”。您的意思是将AU水平平均值(55条总线上每个类别的平均值)叠加在BU水平平均值(特定BU类别的平均值)之上吗?在这种情况下,我叠加了两组平均值:(1)每个AU
的平均值和(2)AU
和BU
的每个组合的平均值。如果您想要所有AU
中每个BU
的平均值,那么您可以执行group\u by(AU,BU,CC)
,而不是group\u by(AU,BU,CC)
。但是,由于平均值不再是分层的,您还需要更改设置最终表格的方式,以明确每个平均值来自哪个级别。让我知道,如果这是你正在寻找的,我可以更新我的答案。是的。就是这样。我需要给出AU平均值,然后分别给出BU平均值。如果你想看,所有的代码都在这里:是的,没错。将事物保存在列表中,无论是多个相似的数据帧还是相关对象的集合(如R建模函数的列表输出,如lm
或glm
),都可以更轻松地进行进一步的分析和处理,还可以保持工作空间整洁,因为你有一个列表,而不是10个或20个或任何单独的对象来跟踪。
```{r}
knitr::kable(df.table %>%
mutate(`Unit Level` = replace(`Unit Level`, duplicated(`Unit Level`), "")))
```
```{r, results="asis"}
library(xtable)
options(xtable.include.rownames=FALSE, xtable.comment=FALSE)
print(xtable(df.table %>%
mutate(`Unit Level` = replace(`Unit Level`, duplicated(`Unit Level`), ""))),
hline.after=c(-1,0,cumsum(table(df.table["Unit Level"]))))
```
library(tidyverse)
# Get averages at the AU-BU level
dfs = df %>%
group_by(AU, BU, CC) %>%
summarise(avg = mean(Score, na.rm = TRUE))
dfs
AU BU CC n avg
1 CBD Constr AUDIT 2 2.0
2 CBD Constr CORC 5 2.8
3 CBD OAO AUDIT 2 1.0
4 CBD OAO CORC 5 2.4
5 CBD Retail AUDIT 2 2.5
6 CBD Retail CORC 4 2.0
# Combine with averages at the AU level
dfs = bind_rows(dfs,
df %>%
group_by(AU, CC) %>%
summarise(avg = mean(Score, na.rm = TRUE)) %>%
mutate(BU = paste("All", AU,"BU")))
dfs
AU BU CC avg
1 CBD Constr AUDIT 2.000000
2 CBD Constr CORC 2.800000
3 CBD OAO AUDIT 1.000000
4 CBD OAO CORC 2.400000
5 CBD Retail AUDIT 2.500000
6 CBD Retail CORC 2.000000
7 CBD All CBD BU AUDIT 1.833333
8 CBD All CBD BU CORC 2.428571
# Spread (does same thing as dcast, but using tidyr spread function)
dfs %>% spread(CC, avg)
AU BU AUDIT CORC
1 CBD All CBD BU 1.833333 2.428571
2 CBD Constr 2.000000 2.800000
3 CBD OAO 1.000000 2.400000
4 CBD Retail 2.500000 2.000000
dfs = df %>%
group_by(AU, BU, CC) %>%
summarise(avg = mean(Score, na.rm = TRUE)) %>%
bind_rows(
df %>%
group_by(AU, CC) %>%
summarise(avg = mean(Score, na.rm = TRUE)) %>%
mutate(BU = paste("All", AU,"BU"))
) %>%
spread(CC, avg)