gio*_*ano 6 r dataframe dplyr tibble
我想枚举分组产生的数据帧/标题的每条记录。该索引是按照定义的顺序排列的。如果我使用 row_number() 它确实会枚举但在组内。但我希望它在不考虑前一组的情况下进行枚举。
这是一个例子。为了简单起见,我使用了最小的数据框:
library(dplyr)
df0 <- data.frame( x1 = rep(LETTERS[1:2],each=2)
, x2 = rep(letters[1:2], 2)
, y = floor(abs(rnorm(4)*10))
)
df0
# x1 x2 y
# 1 A a 12
# 2 A b 24
# 3 B a 0
# 4 B b 12
Run Code Online (Sandbox Code Playgroud)
现在,我将此表分组:
df1 <- df0 %>% group_by(x1,x2) %>% summarize(y=sum(y))
Run Code Online (Sandbox Code Playgroud)
这给了我一个 tibble 类的对象:
# A tibble: 4 x 3
# Groups: x1 [?]
# x1 x2 y
# <fct> <fct> <dbl>
# 1 A a 12
# 2 A b 24
# 3 B a 0
# 4 B b 12
Run Code Online (Sandbox Code Playgroud)
我想使用 row_numer() 向该表添加行号:
df2 <- df1 %>% arrange(desc(y)) %>% mutate(index = row_number())
df2
# A tibble: 4 x 4
# Groups: x1 [2]
# x1 x2 y index
# <fct> <fct> <dbl> <int>
# 1 A b 24 1
# 2 A a 12 2
# 3 B b 12 1
# 4 B a 0 2
Run Code Online (Sandbox Code Playgroud)
row_number() 确实在前一个分组中进行枚举。这不是我的本意。这可以避免首先将 tibble 转换为数据帧:
df2 <- df2 %>% as.data.frame() %>% arrange(desc(y)) %>% mutate(index = row_number())
df2
# x1 x2 y index
# 1 A b 24 1
# 2 A a 12 2
# 3 B b 12 3
# 4 B a 0 4
Run Code Online (Sandbox Code Playgroud)
我的问题是:这种行为是故意的吗?如果是的话:将以前的数据处理合并到tibble中不是很危险吗?包含哪种类型的处理?目前我将把 tibble 转换为 dataframe 以避免这种意外的结果。
详细说明我的评论:是的,保留分组是有意的,并且在许多情况下很有用。如果您不了解group_by
xe2\x80\x94 的工作原理,那么这才是危险的,而且任何函数都是如此。要撤消group_by
,您可以调用ungroup
。
看一下文档group_by
,因为它们非常详尽,并解释了该函数如何与其他函数交互,分组如何分层等。文档还解释了每个调用如何summarise
删除分组层\xe2\x80\x94it在那里你对正在发生的事情感到困惑。
例如,您可以按x1
和进行分组x2
,汇总y
并创建行号,这将根据x1
(summarise
删除一层分组,即删除x2
分组)为您提供行。然后取消分组可以让您根据整个数据框获取行号。
library(dplyr)\n\ndf0 %>%\n group_by(x1, x2) %>%\n summarise(y = sum(y)) %>%\n mutate(group_row = row_number()) %>%\n ungroup() %>%\n mutate(all_df_row = row_number())\n#> # A tibble: 4 x 5\n#> x1 x2 y group_row all_df_row\n#> <fct> <fct> <dbl> <int> <int>\n#> 1 A a 12 1 1\n#> 2 A b 2 2 2\n#> 3 B a 10 1 3\n#> 4 B b 23 2 4\n
Run Code Online (Sandbox Code Playgroud)\n\n一个用例\xe2\x80\x94我可能每天都会这样做\xe2\x80\x94是为了获取多个组内的总和(再次,x1
和x2
),然后找到这些值在较大组内的份额(剥离后)一层分组,这是x1
) 与mutate
。同样,在这里我取消分组以显示份额而不是整个数据框。
df0 %>%\n group_by(x1, x2) %>%\n summarise(y = sum(y)) %>%\n mutate(share_in_group = y / sum(y)) %>%\n ungroup() %>%\n mutate(share_all_df = y / sum(y))\n#> # A tibble: 4 x 5\n#> x1 x2 y share_in_group share_all_df\n#> <fct> <fct> <dbl> <dbl> <dbl>\n#> 1 A a 12 0.857 0.255 \n#> 2 A b 2 0.143 0.0426\n#> 3 B a 10 0.303 0.213 \n#> 4 B b 23 0.697 0.489\n
Run Code Online (Sandbox Code Playgroud)\n\n由reprex 包(v0.2.1)于 2018 年 10 月 11 日创建
\n