【问题标题】:summarise by group of columns using min and maintaing row number使用 min 按列组汇总并保持行号
【发布时间】:2015-02-21 08:51:30
【问题描述】:

我有一个包含 3 列的数据框

df <- data.frame(ID1=c(rep(1,4),rep(2,4)), ID2=rep(1:2,4), value=1:8)

我需要恢复每个组的最小值(ID1,ID2)和这个最小值在原始表中的位置(row.name)。

使用 group_by 和 summarise,我获得了最小值,但我看不到获取位置的方法,因为 summarise 摆脱了未汇总且未用于组的列。

df<-data.frame(ID1=c(rep(1,4),rep(2,4)), ID2=rep(1:2,4), value=1:8)
df[['X']] <- paste0(df$ID1,'.',df$ID2)
df <- group_by( df, X )
df <- summarise( df, Objective=min(value)  )

关于如何解决这个问题的任何想法?

    X Objective Position
1 1.1         1        1
2 1.2         2        2
3 2.1         5        5
4 2.2         6        6

提前致谢

【问题讨论】:

  • 我想如果可以对行的顺序做出假设,它可能会起作用。但它仍然不起作用。我得到:[1] ID1 ID2 值 (或 0-length row.names)

标签: r position min summarization


【解决方案1】:

如果我理解正确并且您已经在使用 dplyr,您可以这样做:

library(dplyr); library(tidyr)
unite(df, X, ID1:ID2, sep = ".") %>% 
     mutate(Position = row_number()) %>% 
     group_by(X) %>% slice(which.min(value))

#Source: local data frame [4 x 3]
#Groups: X
#
#    X value Position
#1 1.1     1        1
#2 1.2     2        2
#3 2.1     5        5
#4 2.2     6        6

或者(仅 dplyr)- 我宁愿使用这个:

mutate(df, Position = row_number()) %>% group_by(ID1, ID2) %>% slice(which.min(value))
#Source: local data frame [4 x 4]
#Groups: ID1, ID2
#
#  ID1 ID2 value Position
#1   1   1     1        1
#2   1   2     2        2
#3   2   1     5        5
#4   2   2     6        6

数据

df <- data.frame(ID1=rep(1:2, each = 4), ID2=rep(1:2,4), value=1:8)

【讨论】:

  • 应该在什么包中找到 slice 方法? eval(expr,envir,enclos)中的错误:找不到函数“slice”
  • 它也在 dplyr 中,你只需要将你的包更新到 CRAN 上的最新版本
  • 谢谢!我不知道我没有在 dplyr 中更新......因此当我尝试时?和 ??我没有什么有用的
【解决方案2】:

以下是我将如何使用data.tablern 将是您的行号)来解决此问题。

library(data.table)
setDT(df, keep.rownames = TRUE)[, .SD[which.min(value)], list(ID1, ID2)]
#    ID1 ID2 rn value
# 1:   1   1  1     1
# 2:   1   2  2     2
# 3:   2   1  5     5
# 4:   2   2  6     6

另一种选择是订购然后选择唯一值

unique(setorder(df, value), by = c("ID1", "ID2"))
#    ID1 ID2 rn value
# 1:   1   1  1     1
# 2:   1   2  2     2
# 3:   2   1  5     5
# 4:   2   2  6     6

这两种方法都不需要创建X

或者使用基础R

df <- df[order(df$value), ]
df[!duplicated(df[, 1:2]), ]
#   ID1 ID2 value
# 1   1   1     1
# 2   1   2     2
# 5   2   1     5
# 6   2   2     6

数据

df <- data.frame(ID1=c(rep(1,4),rep(2,4)), ID2=rep(1:2,4), value=1:8)

【讨论】:

  • 感谢您的回答。我接受了另一个建议,但我从你的建议中学到了很多。
【解决方案3】:

使用Aggregate

数据:

df<-data.frame(ID1=c(rep(1,4),rep(2,4)), ID2=rep(1:2,4), value=1:8)
df[['X']] <- paste0(df$ID1,'.',df$ID2)
df$rn<-row.names(df)                #rn is the row number
df<-df[c("X","rn","value")]
#> df
#    X rn value
#1 1.1  1     1
#2 1.2  2     2
#3 1.1  3     3
#4 1.2  4     4
#5 2.1  5     5
#6 2.2  6     6
#7 2.1  7     7
#8 2.2  8     8

Aggregate 步:

df2<- aggregate(df, by=list(c(df$X)), min)
#> df2
#  Group.1   X rn value
#1     1.1 1.1  1     1
#2     1.2 1.2  2     2
#3     2.1 2.1  5     5
#4     2.2 2.2  6     6

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-31
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多