【问题标题】:sumif in ifelse condition Rifelse 条件 R 中的 sumif
【发布时间】:2017-05-08 06:28:49
【问题描述】:

我有一个包含多列的 DT,我需要在 ifelse 中给出一个条件并相应地进行计算。我希望它按段分组进行计数/总和(计数)。这是DT

Segment  Count  Flag
A        23     Y
B        45     N
A        56     N 
B        212    Y

我希望第四列作为基于标志的段总计数的计数,因此输出应该看起来像这样。对于标志 N,它是每段计数的份额。对于标志 Y,如果 No(N) 变为 Yes(Y),则计算收入百分比,在这种情况下是可以赚取的收入。我很抱歉,因为它很笨拙,但如果您有任何疑问,请在 cmets 中问我。

Segment  Count  Flag   Rev   Value
    A        23     Y  34    ((56/23)*34)/(34+69)
    B        45     N  48    45/(45+212)
    A        56     N  23    56/(56+23)
    B        212    Y  67    ((45/212)*67)/(67+12)
    A        65     Y  69     ...
    B        10     Y  12    ...

感谢任何帮助。谢谢!

【问题讨论】:

  • 这是什么?您已第三次更改预期输出。请珍惜别人的时间
  • 对不起。随着我对数据的推进,我开始知道需要什么。很抱歉浪费了您的时间,但这并没有白费。现在我知道做什么和怎么做。非常感谢!
  • @AbhishekSingh 请参阅asking followup questions的指南
  • 感谢您的讽刺阿伦以及帮助。但它被留下了,因为有什么价值并不重要。
  • 好吧,伙计,我在这里迷路了B 45 N 48 45/(45+212); A 56 N 23 56/(56+23) 'N' 的 212 和 23 有什么不同,或者就像每个元素都有特定的规则。我的问题是为什么不包括65

标签: r if-statement data.table


【解决方案1】:

我们可以通过data.table 做到这一点。将'data.frame'转换为'data.table'(setDT(DT)),按'Segment'分组,通过'Count'除以'Count'的sum来创建'Value'列,然后我们更新Flag 为 'N' 的'Value'

library(data.table)
setDT(DT)[, Value := Count/sum(Count), Segment
              ][Flag == "N", Value := Count/sum(Count), Segment]


DT
#   Segment Count Flag      Value
#1:       A    23    Y 0.18852459
#2:       B    45    N 1.00000000
#3:       A    56    N 1.00000000
#4:       B   212    Y 0.78810409
#5:       A    43    Y 0.35245902
#6:       B    12    Y 0.04460967

只需检查 OP 的预期输出“值”

> 23/122
#[1] 0.1885246
> 212/269
#[1] 0.7881041
> 43/122
#[1] 0.352459
> 12/269
#[1] 0.04460967

更新3

基于 Op 帖子中的更新 No:3

s1 <-  setDT(DT1)[, .(rn = .I[Flag == "Y"], Value = (Rev[Flag=="Y"] *
    (Count[Flag == "N"]/Count[Flag=="Y"]))/sum(Rev[Flag == "Y"])), Segment]
s2 <-  DT1[, .(rn = .I[Flag == "N"], Value = Count[Flag == "N"]/(Count[Flag == "N"] + 
               Count[Flag=="Y"][1])), Segment]

DT1[, Value := rbind(s1, s2)[order(rn)]$Value]
DT1
#   Segment Count Flag Rev     Value
#1:       A    23    Y  34 0.8037146
#2:       B    45    N  48 0.1750973
#3:       A    56    N  23 0.7088608
#4:       B   212    Y  67 0.1800215
#5:       A    65    Y  69 0.5771471
#6:       B    10    Y  12 0.6835443


>((56/23)*34)/(34+69)
#[1] 0.8037146
> 45/(45+212)
#[1] 0.1750973
>  56/(56+23)
#[1] 0.7088608
> ((45/212)*67)/(67+12)
#[1] 0.1800215

数据

DT <- structure(list(Segment = c("A", "B", "A", "B", "A", "B"), Count = c(23L, 
45L, 56L, 212L, 43L, 12L), Flag = c("Y", "N", "N", "Y", "Y", 
"Y")), .Names = c("Segment", "Count", "Flag"), row.names = c(NA, 
-6L), class = "data.frame")

DT1 <- structure(list(Segment = c("A", "B", "A", "B", "A", "B"), Count = c(23L, 
45L, 56L, 212L, 65L, 10L), Flag = c("Y", "N", "N", "Y", "Y", 
"Y"), Rev = c(34L, 48L, 23L, 67L, 69L, 12L)), .Names = c("Segment", 
"Count", "Flag", "Rev"), class = "data.frame", row.names = c(NA, 
-6L))

【讨论】:

  • 嗨,setDT是什么
  • @AbhishekSingh 是将'data.frame'转换为'data.table'的函数
  • @AbhishekSingh 好的,那就不用申请了setDT
  • 我很抱歉让 Arun 感到困惑,但它必须根据第二个条件中的标志来做,对于第一个条件,它应该将所有内容相加,而与标志无关。在这种情况下,该怎么办。编辑问题。
  • @AbhishekSingh 是的,它是根据第二列中的标志完成的。请检查i 条件,即Flag == "Y"
【解决方案2】:

或者,我们也可以使用dplyr pkg 来实现...

根据@Aramis7d 提供的建议进行更新 - 谢谢!

library(data.table)
df <- fread("Segment  Count  Flag
 A        23     Y
    B        45     N
            A        56     N
            B        212    Y
            A        43     Y
            B        12     Y")

library(dplyr)

df %>% 
      group_by(Segment) %>% 
      mutate(Value = Count/sum(Count)) %>%
      group_by(Segment, Flag) %>%
      mutate(Value = if_else( Flag == "N", Count/sum(Count), Value))

【讨论】:

  • 确定这会根据 OP 的要求产生正确的输出吗?
  • 我阅读了初稿,而不是后来编辑的 :-) 但你完成了剩下的部分......无论如何,它看起来很简单并且符合你刚刚所做的要求......
  • 看来 OP 还没有决定呢
  • @ManojKumar 这对我不起作用,或者我不知道如何使用它。你可以笑得更开心。
  • 来吧兄弟。我们的 cmets 没有讽刺意味。我们都在努力帮助你..不要采取其他方式......
猜你喜欢
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
  • 1970-01-01
相关资源
最近更新 更多