多个类别的R max

时间:2018-01-28 05:43:31

标签: r loops dataframe categories

我的数据有点像这样(当然还有更多行):

Age     Work Zone     SomeNumber
26      1          2.61
32      4          8.42
41      2          9.71
45      2          4.14
64      3          6.04
56      1          5.28
37      4          7.93

我希望在每个年龄或以下的每个区域获得最大的SomeNumber。 SomeNumber会随着年龄的增长而增加,所以我希望2区32岁以下的SomeNumber最高是由一个年龄在31岁以上的人来实现的,但实际上可能是27岁的人。

为此,我编写了一个嵌套for循环:

for(i in zonelist){
  temp = data[data$zone==i,]
  for(j in 1:max(data$age)){
    temp.lessequal=c(temp.lessequal,max((temp[temp$Age<=j,])$SomeNumber))
  }
  #plot temp.lessequal or save it at this point
}

当然非常慢。我怎么能更快地做到这一点?我已经查看了订单功能,一次按两列排序,但这并不能让我获取每组的最大值。

3 个答案:

答案 0 :(得分:1)

数据:

df1 <- read.table(text='Age Work_Zone  SomeNumber
26      1          2.61
                   32      4          8.42
                   41      2          9.71
                   45      2          4.14
                   64      3          6.04
                   56      1          5.28
                   37      4          7.93', 
                   header = TRUE)

<强>代码:

df2 <- with( df1, df1[ Age <= 32, ] )  # extract rows with Age <= 32
# get maximum of someNumber by aggregating with work_zone and then merging with df1 to combine the age column
merge(aggregate(SomeNumber ~ Work_Zone, data = df2, max), df2) 
#   Work_Zone SomeNumber Age
# 1         1       2.61  26
# 2         4       8.42  32

答案 1 :(得分:0)

使用库data.table,您可以选择小于所需年龄的行,然后按工作区输出每个工作区的max(somenumber)及其各自的年龄。

library(data.table)
setDT(df1)[Age<=32,.(max(SomeNumber),Age),by=Work_Zone]
   Work_Zone   V1 Age
1:         1 2.61  26
2:         4 8.42  32

答案 2 :(得分:0)

似乎OP正在根据特定列(max)上的<=条件查找Age值。

在这种情况下使用sqldf非常方便,以便解释逻辑。一种解决方案可能是:

# Data 
df <- read.table(text = "Age     Work_Zone     SomeNumber
26      1          2.61
32      4          8.42
41      2          9.71
45      2          4.14
64      3          6.04
56      1          5.28
37      4          7.93", header = T, stringsAsFactors = F)

library(sqldf)
df3 <- sqldf("select df1.Work_Zone, df1.Age, max(df2.SomeNumber) from df df1 
       inner join df df2 on df1.Work_Zone = df2.Work_Zone 
       WHERE df2.Age <= df1.Age 
       GROUP BY df1.Work_Zone, df1.Age")

# Result:
#   Work_Zone Age max(df2.SomeNumber)
# 1         1  26                2.61
# 2         1  56                5.28
# 3         2  41                9.71
# 4         2  45                9.71
# 5         3  64                6.04
# 6         4  32                8.42
# 7         4  37                8.42