在R中分组的情况

时间:2017-10-10 08:03:21

标签: r

我想在R中执行sumif等效操作。

每当ID和类型匹配且标志为0时,我想计算一个百分比(在下面的示例中,它是(1 /(9 + 30826))否则我想将其保持为0%(在那里是没有0标志)

以下是示例:

ID  Type    Flag  Value1  Value2 
1   Apple   0        1     9        
1   Apple   1     29312    30826  
1   Orange  1     2222     3423
2   Orange  1     24566    32234

我想要以下结果:

ID  Type    Value1  Value2  Result
1   Apple   29313   30835   0.0032%
1   Orange  2222    3423    0%
2   Orange  24566   32234   0%

2 个答案:

答案 0 :(得分:1)

将data.frame转换为' data.table' (setDT(df1)),按' ID','类型'分组,如果观察次数大于1,则执行OP中显示的除法发布或者返回0.删除'标记'列,然后获取' Value1'的sum和' Value2'按ID'分组和'键入'并采取unique

library(data.table)
 setDT(df1)[, Result := if(.N >1) round(100*Value1[1]/(Value2[1]+Value2[2]), 3) 
                                       else 0, .(ID, Type)]
df2 <- df1[, -3, with = FALSE]
df2[, (3:4) := lapply(.SD, sum), .SDcols = Value1:Value2, .(ID, Type)]
unique(df2)
#   ID   Type Value1 Value2 Result
#1:  1  Apple  29313  30835  0.003
#2:  1 Orange   2222   3423  0.000
#3:  2 Orange  24566  32234  0.000

或者我们可以在单个流程中使用tidyverse。按照&#39; ID&#39;,&#39;类型&#39;进行分组后,创建&#39;结果&#39;列,然后获取sum&#39;值columns with mutate_at , remove the 'Flag' and get the distinct`行

library(dplyr)
df1 %>%
    group_by(ID, Type) %>% 
    mutate(Result = round(100*if(n()==2) first(Value1)/(first(Value2)+last(Value2))
                             else 0, 3)) %>% 
    mutate_at(vars(matches('Value')), sum) %>% 
    select(-Flag) %>% 
    distinct
# A tibble: 3 x 5
# Groups:   ID, Type [3]
#      ID   Type Value1 Value2 Result
#    <int>  <chr>  <int>  <int>  <dbl>
#1     1  Apple  29313  30835  0.003
#2     1 Orange   2222   3423  0.000
#3     2 Orange  24566  32234  0.000

答案 1 :(得分:1)

您可以使用ave()

d <- read.table(header=TRUE, text="ID  Type    Flag  Value1  Value2 
1   Apple   0        1     9        
1   Apple   1     29312    30826  
1   Orange  1     2222     3423
2   Orange  1     24566    32234")

d$Result <- ave(ifelse(d$Flag==0, d$Value1, 0), d$ID, d$Type, FUN=sum) / ave(d$Value2, d$ID, d$Type, FUN=sum) 
d$Value1 <- ave(d$Value1, d$ID, d$Type, FUN=sum)
d$Value2 <- ave(d$Value2, d$ID, d$Type, FUN=sum)
dResult <- d[d$Flag==1,]
dResult
# > dResult
#   ID   Type Flag Value1 Value2       Result
# 2  1  Apple    1  29313  30835 3.243068e-05
# 3  1 Orange    1   2222   3423 0.000000e+00
# 4  2 Orange    1  24566  32234 0.000000e+00

如果{[1}}位于[%],您可以执行$Result