【问题标题】:Compare each row within each group比较每组中的每一行
【发布时间】:2016-11-18 23:51:15
【问题描述】:

以下数据集是可重现的

group <- c(1,1,2,2,3,3)
parameter <- c("A","B","A","B","A","B")
values <- c(10,20,20,5,30,50)
df <- data.frame(group,parameter,values)

group parameter values
    1         A     10
    1         B     20
    2         A     20
    2         B      5
    3         A     30
    3         B     50

我想在每个组中检查 A > B(将此结果存储在整个组的第四列中)

如果是 -> 真,如果不是 -> 假

新的 Df:

group parameter values  status
    1         A     10      FALSE
    1         B     20      FALSE
    2         A     20      TRUE
    2         B      5      TRUE
    3         A     30      FALSE
    3         B     50      FALSE

方法

with(df, ave(values,group, FUN = function(x) ))

我无法想象函数内部的代码是什么。有人可以帮我吗

更新:状态应按照每组的值列(从最高到最低)进行排名

group parameter values  status
    1         A     10      2
    1         B     20      1
    2         A     20      1
    2         B      5      2
    3         A     30      2
    3         B     50      1

【问题讨论】:

  • 每组中是否总是恰好有 1 个 A 和 1 B 值?
  • 是的,每组中正好有 1 个 A 和 1 B 值

标签: r


【解决方案1】:

我们可以试试data.table。将“data.frame”转换为“data.table”(setDT(df)),按“组”分组,比较“参数”为“A”的“值”与“B”的值并赋值(:= ) 创建“状态”

library(data.table)
setDT(df)[, status := values[parameter=="A"]>values[parameter=="B"], by = group]
df
#   group parameter values status
#1:     1         A     10  FALSE
#2:     1         B     20  FALSE
#3:     2         A     20   TRUE
#4:     2         B      5   TRUE
#5:     3         A     30  FALSE
#6:     3         B     50  FALSE

对于rank,在按“组”分组后在“值”上使用frank

setDT(df)[, status:= frank(-values), group]
df
#   group parameter values status
#1:     1         A     10      2
#2:     1         B     20      1
#3:     2         A     20      1
#4:     2         B      5      2
#5:     3         A     30      2
#6:     3         B     50      1

或者使用ave,我们可以将第一个值与第二个值进行比较(假设“参数”是有序的,并且每个“组”只有两个元素

df$status <- with(df, as.logical(ave(values, group, FUN = function(x) x[1] > x[2])))

或者另一种选择是order数据集的第一列(如果它没有排序),通过回收逻辑索引将“值”子集,比较和复制每个逻辑值2。

df1 <- df[do.call(order, df[1:2]), ]
rep(df1$values[c(TRUE, FALSE)] > df1$values[c(FALSE, TRUE)], each = 2)

【讨论】:

  • 嘿,这很酷。假设如果我想对参数进行排名,解决方案是否在同一行?
  • @Hardik 你能用预期的排名更新你的帖子吗
【解决方案2】:

还有使用dplyrtidyverse解决方案:

    library(dplyr)

    df %>% 
      group_by(group) %>% 
      mutate(status = ifelse(values[parameter == "A"] > values[parameter == "B"], TRUE, FALSE),
             rank = min_rank(-values))

Source: local data frame [6 x 5]
Groups: group [3]

  group parameter values status  rank
  (dbl)    (fctr)  (dbl)  (lgl) (int)
1     1         A     10  FALSE     2
2     1         B     20  FALSE     1
3     2         A     20   TRUE     1
4     2         B      5   TRUE     2
5     3         A     30  FALSE     2
6     3         B     50  FALSE     1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-08
    • 2019-02-26
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 2020-08-13
    相关资源
    最近更新 更多