library(dplyr)
a <- data_frame(id = c("A","A","A","B","B","B"),
b = c(1.2, 1.5, 1.8, 1.1, 1.6, 1.4))
现在,我想为id中的每个catergories检索最接近1.43的值。 我以为我可以用:
a %>% group_by(id) %>% nth(which.min(abs(.$b-1.43)))
但是dplyr声明
Error: Don't know how to generate default for object of class grouped_df/tbl_df/tbl/data.frame
答案 0 :(得分:10)
which.min()
返回数字(或逻辑)向量的(第一个)最小值或最大值的索引。如果有多个相等的值,则彼此接近1.43并且您想要保留所有这些内容,您可以使用filter()
:
a %>% group_by(id) %>% filter(abs(b - 1.43) == min(abs(b - 1.43)))
#Source: local data frame [2 x 2]
#Groups: id [2]
# id b
# <chr> <dbl>
#1 A 1.5
#2 B 1.4
如果您更喜欢坚持使用nth()
函数,并且每个组只有一个值,则可以将其包装在汇总函数中,以便将其应用于每个组,并且还可以根据到?nth()
,您还需要将向量作为参数传递给函数:
a %>% group_by(id) %>% summarise(b = nth(b, which.min(abs(b-1.43))))
# A tibble: 2 × 2
# id b
# <chr> <dbl>
#1 A 1.5
#2 B 1.4
答案 1 :(得分:4)
离你的不太远
a %>% group_by(id) %>% summarise(which.min(abs(b-1.43)))
# A tibble: 2 × 2
# id `which.min(abs(b - 1.43))`
# <chr> <int>
# 1 A 2
# 2 B 3
或者,如果您需要值,而不是索引:
a %>% group_by(id) %>% summarise(b[which.min(abs(b-1.43))])
# A tibble: 2 × 2
# id `b[which.min(abs(b - 1.43))]`
# <chr> <dbl>
# 1 A 1.5
# 2 B 1.4
答案 2 :(得分:4)
有几种方法可以做到这一点。
这是一个dplyr
解决方案(使用this answer找到):
a %>%
group_by(id) %>%
slice(which.min(abs(b - 1.43)))
id b
<chr> <dbl>
1 A 1.5
2 B 1.4
这是一个基本解决方案:
do.call('rbind', by(a, a$id, function(x) x[which.min(abs(x$b - 1.43)), ]))
id b
<chr> <dbl>
1 A 1.5
2 B 1.4
这是一个hacky dplyr
解决方案:
a %>%
mutate(AbsDiff = abs(b - 1.43)) %>%
group_by(id) %>%
mutate(AbsDiff_r = rank(AbsDiff, ties.method = 'first')) %>%
filter(AbsDiff_r == 1)
id b AbsDiff AbsDiff_r
<chr> <dbl> <dbl> <int>
1 A 1.5 0.07 1
2 B 1.4 0.03 1
答案 3 :(得分:2)
以下是data.table
library(data.table)
setDT(a)[, .(b= b[which.min(abs(b-1.43))]) , id]
# id b
#1: A 1.5
#2: B 1.4