【问题标题】:Compare values in a grouped data frame with corresponding value in a vector将分组数据框中的值与向量中的对应值进行比较
【发布时间】:2021-02-25 04:39:09
【问题描述】:

假设我有一个如下的 data.frame:

u <- as.numeric(rep(rep(1:5,3)))
w <- as.factor(c(rep("a",5), rep("b",5), rep("c",5)))
q <- data.frame(w,u)

q

  w u
1  a 1
2  a 2
3  a 3
4  a 4
5  a 5
6  b 1
7  b 2
8  b 3
9  b 4
10 b 5
11 c 1
12 c 2
13 c 3
14 c 4
15 c 5

和向量:

v <- c(2,3,1)

现在我想找到相应组 [i] 中的第一行,其中向量“v”中的值 [i] 大于列“u”中的值。

结果应该是这样的:

1 a 3
2 b 4
3 c 2

我试过了:

fun <- function (m) {
  first(which(m[,2]>v))
}

ddply(q, .(w), summarise, fun(q))

and got as a result: 

  w fun(q)
1 a      3
2 b      3
3 c      3

因此,ddply 似乎只从向量“v”中获取第一个值。

有人知道怎么解决吗?

【问题讨论】:

  • ddply 返回单个值,因为您正在应用整个列 m[,2]q[,2] 以及 v 是完整向量而不是每个组的对应元素这一​​事实

标签: r


【解决方案1】:

我们可以通过从 'q' 的 'w' 列中创建一个带有 'w' 作为 unique 值的 data.frame 来加入 vector,然后执行 group_by 'w' 并获取第一行u 大于相应“向量”列值的索引

library(dplyr)
q %>% 
   left_join(data.frame(w = unique(q$w), new = v)) %>%
   group_by(w) %>% 
   summarise(n = which(u > new)[1]) 
   # // or use findInterval
   #summarise(n = findInterval(new[1], u)+1)

-输出

# A tibble: 3 x 2
#  w         n
#* <fct> <int>
#1 a         3
#2 b         4
#3 c         2

或在split通过'w'列输入数据后使用Map

Map(function(x, y) which(x$u > y)[1], split(q,q$w), v)
#$a
#[1] 3

#$b
#[1] 4

#$c
#[1] 2

OP 提到比较是从头开始的,这是不正确的,因为我们有一个group_by 操作。如果我们创建一列序列,它会在每个组中重置

q %>% 
    left_join(data.frame(w = unique(q$w), new = v)) %>%
    group_by(w) %>% 
 mutate(rn = row_number())
Joining, by = "w"
# A tibble: 15 x 4
# Groups:   w [3]
   w         u   new    rn
   <fct> <dbl> <dbl> <int>
 1 a         1     2     1
 2 a         2     2     2
 3 a         3     2     3
 4 a         4     2     4
 5 a         5     2     5
 6 b         1     3     1
 7 b         2     3     2
 8 b         3     3     3
 9 b         4     3     4
10 b         5     3     5
11 c         1     1     1
12 c         2     1     2
13 c         3     1     3
14 c         4     1     4
15 c         5     1     5

【讨论】:

  • 感谢您的建议。不幸的是,它不起作用(尽管它得到了所谓的正确结果。这段代码也从头开始查找 u > new。但是,对于第二个值,它应该从组 b 的第一个值开始。
  • @RaphaelKnecht 你有没有注意到我使用了group_by(w)。因此,它以正确的方式进行比较,即为每个分组重置 row_number()
  • @RaphaelKnecht 你可以查看我创建的rn。它在每个组重置
  • @RaphaelKnecht 如果你能提供这个失败的具体用例,那就太好了
  • 对不起,我的错。现在可以了。非常感谢!
【解决方案2】:

使用data.table:对于每个'w' (by = w),使用组索引.GRP 子集'v'。将该值与“u”(v[.GRP] &lt; u) 进行比较。获取第一个TRUEwhich.max)的索引:

library(data.table)
setDT(q)[ , which.max(v[.GRP] < u), by = w]
#    w V1
# 1: a  3
# 2: b  4
# 3: c  2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多