我想在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%
答案 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