我想使用SQL或R对数据进行分组,以便为每个Subarea_codes
和Company
获取最高或最低10 Area_code
。实质上:Subarea_codes
中的Area_codes
,其中每个Company
都有最大或最小的结果。
data.csv
Area_code Subarea_code Company Result
10 101 A 15
10 101 P 10
10 101 C 4
10 102 A 10
10 102 P 8
10 102 C 5
11 111 A 15
11 111 P 20
11 111 C 5
11 112 A 10
11 112 P 5
11 112 C 10
result.csv should be like this
Company Area_code Largest_subarea_code Result Smallest_subarea_code Result
A 10 101 15 102 10
P 10 101 10 102 8
C 10 102 5 101 4
A 11 111 15 112 10
P 11 111 20 112 5
C 11 112 10 111 5
在每个Area_code
内,可能有数百个Subarea_codes
,但我只想要每个公司的最高和最低10个。
这也不必在一个查询中解析,但可以分为两个查询,意味着最小值显示在results_10_smallest中,最大值显示在result_10_largest中。但是我希望我能用一个查询来完成每个结果。
我尝试过的事情:
SELECT Company, Area_code, Subarea_code MAX(Result)
AS Max_result
FROM data
GROUP BY Subarea_code
ORDER BY Company
;
这为我提供了每个Subarea_code中具有最高结果的Companies
。这意味着:A,A,P,A-C为上述数据。
答案 0 :(得分:6)
使用sqldf
包:
df <- read.table(text="Area_code Subarea_code Company Result
10 101 A 15
10 101 P 10
10 101 C 4
10 102 A 10
10 102 P 8
10 102 C 5
11 111 A 15
11 111 P 20
11 111 C 5
11 112 A 10
11 112 P 5
11 112 C 10", header=TRUE)
library(sqldf)
mymax <- sqldf("select Company,
Area_code,
max(Subarea_code) Largest_subarea_code
from df
group by Company,Area_code")
mymaxres <- sqldf("select d.Company,
d.Area_code,
m.Largest_subarea_code,
d.Result
from df d, mymax m
where d.Company=m.Company and
d.Subarea_code=m.Largest_subarea_code")
mymin <- sqldf("select Company,
Area_code,
min(Subarea_code) Smallest_subarea_code
from df
group by Company,Area_code")
myminres <- sqldf("select d.Company,
d.Area_code,
m.Smallest_subarea_code,
d.Result
from df d, mymin m
where d.Company=m.Company and
d.Subarea_code=m.Smallest_subarea_code")
result <- sqldf("select a.*, b.Smallest_subarea_code,b.Result
from mymaxres a, myminres b
where a.Company=b.Company and
a.Area_code=b.Area_code")
答案 1 :(得分:5)
如果您已在R中执行此操作,为什么不使用SQL语法来使用效率更高的data.table
而不是sqldf
?假设data
是您的数据集,只需:
library(data.table)
setDT(data)[, list(Largest_subarea_code = Subarea_code[which.max(Result)],
Resultmax = max(Result),
Smallest_subarea_code = Subarea_code[which.min(Result)],
Resultmin = min(Result)), by = list(Company, Area_code)]
# Company Area_code Largest_subarea_code Resultmax Smallest_subarea_code Resultmin
# 1: A 10 101 15 102 10
# 2: P 10 101 10 102 8
# 3: C 10 102 5 101 4
# 4: A 11 111 15 112 10
# 5: P 11 111 20 112 5
# 6: C 11 112 10 111 5
答案 2 :(得分:1)
显示的输出与描述之间似乎存在差异。描述要求每个区号/公司的前10名和后10名结果,但样本输出仅显示前1和后1。例如,对于区号10和公司A子区域101是顶部,结果为15并且子区域102是第二大的,结果为10,因此根据描述,该公司/区域代码组合应该有两行。 (如果有更多数据,那么该公司/区号组合最多可以有10行。)
我们给出两个答案。第一个假设每个公司和区域代码需要前10个和后10个,如问题的描述,第二个假设每个公司和区域代码的顶部和底部,如问题的样本输出
1)上/下10
这里我们假设需要每个公司/区域代码的前10个和后10个结果。如果它只是顶部和底部,那么稍后会看到(2)(或者在代码中用10代替10)。 Bottom10
是相同区域代码的10个或更少子区域以及具有相同或更小结果的公司的所有行。 Top10
类似。
library(sqldf)
Bottom10 <- sqldf("select a.Company,
a.Area_code,
a.Subarea_code Bottom_Subarea,
a.Result Bottom_Result,
count(*) Bottom_Rank
from df a join df b
on a.Company = b.Company and
a.Area_code = B.Area_code and
b.Result <= a.Result
group by a.Company, a.Area_code, a.Subarea_code
having count(*) <= 10")
Top10 <- sqldf("select a.Company,
a.Area_code,
a.Subarea_code Top_Subarea,
a.Result Top_Result,
count(*) Top_Rank
from df a join df b
on a.Company = b.Company and
a.Area_code = B.Area_code and
b.Result >= a.Result
group by a.Company, a.Area_code, a.Subarea_code
having count(*) <= 10")
说明表明您希望每个公司/地区代码的前10名或后10名,在这种情况下只需使用上述结果之一。如果你想组合它们,我们在下面显示合并。我们添加了一个Rank列来表示最小/最大(Rank为1),第二个最小/最大(Rank为2)等。
sqldf("select t.Area_code,
t.Company,
t.Top_Rank Rank,
t.Top_Subarea,
t.Top_Result,
b.Bottom_Subarea,
b.Bottom_Result
from Bottom10 b join Top10 t
on t.Area_code = b.Area_code and
t.Company = b.Company and
t.Top_Rank = b.Bottom_Rank
order by t.Area_code, t.Company, t.Top_Rank")
,并提供:
Area_code Company Rank Top_Subarea Top_Result Bottom_Subarea Bottom_Result
1 10 A 1 101 15 102 10
2 10 A 2 102 10 101 15
3 10 C 1 102 5 101 4
4 10 C 2 101 4 102 5
5 10 P 1 101 10 102 8
6 10 P 2 102 8 101 10
7 11 A 1 111 15 112 10
8 11 A 2 112 10 111 15
9 11 C 1 112 10 111 5
10 11 C 2 111 5 112 10
11 11 P 1 111 20 112 5
12 11 P 2 112 5 111 20
请注意,如果存在关联,此格式不太合理,实际上,可能会为公司/区域代码生成10行以上,因此您可能只想使用个人Top10
和{{1} } 在这种情况下。如果这是一个问题,你也可以考虑抖动Bottom10
:
df$Result
2)仅限上/下
这里我们只给出每个公司/地区代码的顶部和底部结果以及相应的子区域。请注意,这使用了sqlite支持的SQL扩展,并且SQL代码基本上更简单:
df$Result <- jitter(df$Result)
# now perform SQL statements
这给出了:
Bottom1 <- sqldf("select Company,
Area_code,
Subarea_code Bottom_Subarea,
min(Result) Bottom_Result
from df
group by Company, Area_code")
Top1 <- sqldf("select Company,
Area_code,
Subarea_code Top_Subarea,
max(Result) Top_Result
from df
group by Company, Area_code")
sqldf("select a.Company,
a.Area_code,
Top_Subarea,
Top_Result,
Bottom_Subarea
Bottom_Result
from Top1 a join Bottom1 b
on a.Company = b.Company and
a.Area_code = b.Area_code
order by a.Area_code, a.Company")
更新更正并添加(2)。
答案 3 :(得分:0)
以上答案可以获取最大结果。
这解决了前10个问题:
data.top <- data[ave(-data$Result, data$Company, data$Area_code, FUN = rank) <= 10, ]
答案 4 :(得分:0)
在此脚本中,用户声明公司。然后该脚本指示最大前10个结果(最小值的同意值)。
Result=NULL
A <- read.table(/your-file.txt",header=T,sep="\t",na.string="NA")
Company<-A$Company=="A" #can be A, C, P or other values
Subarea<-unique(A$Subarea)
for (i in 1:length(unique(A$Subarea)))
{Result[i]<-max(A$Result[Company & A$Subarea_code==Subarea[i]])}
Res1<-t((rbind(Subarea,Result)))
Res2<-Res1[order(-Res1[,2]),]
Res2[1:10,]