如何在R中像在SQL中一样分组?
我有这个表格测试 我认为在SQL中是这样的,至少我记得:如何在R中像在SQL中一样分组?,r,group-by,aggregate,R,Group By,Aggregate,我有这个表格测试 我认为在SQL中是这样的,至少我记得: proc sql; create table test as select a.T, a.Y, sum(case when Y eq a.Y or Y eq a.Y+1 then S else 0 end) as x from test as a group by T, Y; end; 如果我理解正确,您可以使用tidyverse方法 require(tidyverse) test %>% group_by(Y) %>
proc sql;
create table test as select
a.T,
a.Y,
sum(case when Y eq a.Y or Y eq a.Y+1 then S else 0 end) as x
from test as a
group by T, Y;
end;
如果我理解正确,您可以使用tidyverse方法
require(tidyverse)
test %>%
group_by(Y) %>%
mutate(x = sum(S, na.rm = TRUE)) %>%
ungroup()
T Y S x
<dbl> <dbl> <dbl> <dbl>
1 1. 2011. 1. 3.
2 1. 2012. 1. 4.
3 1. 2012. 3. 4.
4 1. 2013. 2. 4.
5 1. 2014. 1. 5.
6 2. 2011. 2. 3.
7 2. 2013. 1. 4.
8 2. 2013. 1. 4.
9 2. 2014. 3. 5.
10 2. 2014. 1. 5.
如果我理解正确,您可以使用tidyverse方法
require(tidyverse)
test %>%
group_by(Y) %>%
mutate(x = sum(S, na.rm = TRUE)) %>%
ungroup()
T Y S x
<dbl> <dbl> <dbl> <dbl>
1 1. 2011. 1. 3.
2 1. 2012. 1. 4.
3 1. 2012. 3. 4.
4 1. 2013. 2. 4.
5 1. 2014. 1. 5.
6 2. 2011. 2. 3.
7 2. 2013. 1. 4.
8 2. 2013. 1. 4.
9 2. 2014. 3. 5.
10 2. 2014. 1. 5.
尝试以下左自联接:
library(sqldf)
sqldf("select a.*, sum(b.S) as x
from test a
left join test b on a.T = b.T and b.Y between a.Y-1 and a.Y
group by a.rowid")
给予:
T Y S x
1 1 2011 1 1
2 1 2012 1 5
3 1 2012 3 5
4 1 2013 2 6
5 1 2014 1 3
6 2 2011 2 2
7 2 2013 1 2
8 2 2013 1 2
9 2 2014 3 6
10 2 2014 1 6
笔记
这被用作产生上述输出的输入:
test <- structure(list(T = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), Y = c(2011,
2012, 2012, 2013, 2014, 2011, 2013, 2013, 2014, 2014), S = c(1,
1, 3, 2, 1, 2, 1, 1, 3, 1)), row.names = c(NA, -10L), class = "data.frame")
尝试以下左自联接:
library(sqldf)
sqldf("select a.*, sum(b.S) as x
from test a
left join test b on a.T = b.T and b.Y between a.Y-1 and a.Y
group by a.rowid")
给予:
T Y S x
1 1 2011 1 1
2 1 2012 1 5
3 1 2012 3 5
4 1 2013 2 6
5 1 2014 1 3
6 2 2011 2 2
7 2 2013 1 2
8 2 2013 1 2
9 2 2014 3 6
10 2 2014 1 6
笔记
这被用作产生上述输出的输入:
test <- structure(list(T = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2), Y = c(2011,
2012, 2012, 2013, 2014, 2011, 2013, 2013, 2014, 2014), S = c(1,
1, 3, 2, 1, 2, 1, 1, 3, 1)), row.names = c(NA, -10L), class = "data.frame")
使用dplyr::left_连接的一个选项可以通过使用自连接实现。其概念是在Y增加1后将test与test连接起来。现在,如果使用left_join进行连接,那么每一行都将使用一个小于Y值1的行进行连接。最后,必须将S.x和S.Y列按行相加
library(tidyverse)
test %>% left_join(mutate(., Y = Y+1), by=c("T", "Y")) %>%
rowwise() %>%
mutate(x = sum(S.x, S.y, na.rm = TRUE)) %>%
select(T, Y, S = S.x, x) %>%
as.data.frame()
# T Y S x
# 1 1 2011 1 1
# 2 1 2012 1 2
# 3 1 2012 3 4
# 4 1 2013 2 3
# 5 1 2013 2 5
# 6 1 2014 1 3
# 7 2 2011 2 2
# 8 2 2013 1 1
# 9 2 2013 1 1
# 10 2 2014 3 4
# 11 2 2014 3 4
# 12 2 2014 1 2
# 13 2 2014 1 2
使用dplyr::left_连接的一个选项可以通过使用自连接实现。其概念是在Y增加1后将test与test连接起来。现在,如果使用left_join进行连接,那么每一行都将使用一个小于Y值1的行进行连接。最后,必须将S.x和S.Y列按行相加
library(tidyverse)
test %>% left_join(mutate(., Y = Y+1), by=c("T", "Y")) %>%
rowwise() %>%
mutate(x = sum(S.x, S.y, na.rm = TRUE)) %>%
select(T, Y, S = S.x, x) %>%
as.data.frame()
# T Y S x
# 1 1 2011 1 1
# 2 1 2012 1 2
# 3 1 2012 3 4
# 4 1 2013 2 3
# 5 1 2013 2 5
# 6 1 2014 1 3
# 7 2 2011 2 2
# 8 2 2013 1 1
# 9 2 2013 1 1
# 10 2 2014 3 4
# 11 2 2014 3 4
# 12 2 2014 1 2
# 13 2 2014 1 2
我并不完全理解您试图计算的内容,但您可以尝试使用data.tables。语法是data.table[WHERE,SELECT,GROUP_BY],如果您习惯于SQL的话,这是很熟悉的。应该是这样的:
library(data.table)
test.dt <- as.data.table(test)
test.dt[ Y >= Y-1, x := sum(S), by = .(T, Y) ]
其中:=表示要创建一个名为x的新列,而不使用它,它将只显示结果。我不完全理解您试图计算的内容,但您可以尝试使用data.tables。语法是data.table[WHERE,SELECT,GROUP_BY],如果您习惯于SQL的话,这是很熟悉的。应该是这样的:
library(data.table)
test.dt <- as.data.table(test)
test.dt[ Y >= Y-1, x := sum(S), by = .(T, Y) ]
其中:=表示要创建一个名为x的新列,而不使用它,它将只显示结果。Perfect!不仅是我期望的结果,而且是我寻找SQL的方式。另外,纠正结果我不好,你给出了正确的答案。太完美了!不仅是我期望的结果,而且是我寻找SQL的方式。另外,纠正结果我不好,你给出了正确的答案。Thks