如何在R中的分组数据中查找某个观察的最后一次出现?

时间:2016-02-26 10:26:24

标签: r dplyr grouping

我有在R中使用dplyr分组的数据。我想在每组中找到最后一次出现的观察('B')等于或大于1(1,2,3或4)('A '),就他们发生的'日'而言。我希望每个组的'day'值在新列中给出。

例如,给定以下数据样本,按A分组(这已经简化,我的数据实际上按3个变量分组):

A  B  day
a  2  1
a  2  2
a  1  5
a  0  8
b  3  1
b  3  4
b  3  6 
b  0  7 
b  0  9
c  1  2 
c  1  3
c  1  4

我想实现以下目标:

A  B  day last
a  2  1   5
a  2  2   5
a  1  5   5
a  0  8   5
b  3  1   6
b  3  4   6
b  3  6   6
b  0  7   6
b  0  9   6
c  1  2   4
c  1  3   4
c  1  4   4

我希望这是有道理的,非常感谢你的帮助!我在网上彻底搜索了我的答案但找不到任何东西。但是,如果我不小心重复了一个问题,那么我道歉。

2 个答案:

答案 0 :(得分:2)

我们可以尝试

library(data.table)
setDT(df1)[, last := day[tail(which(B>=1),1)] , A]
df1
#    A B day last
# 1: a 2   1    5
# 2: a 2   2    5
# 3: a 1   5    5
# 4: a 0   8    5
# 5: b 3   1    6
# 6: b 3   4    6
# 7: b 3   6    6
# 8: b 0   7    6
# 9: b 0   9    6
#10: c 1   2    4
#11: c 1   3    4
#12: c 1   4    4

或使用dplyr

library(dplyr)
df1 %>%
   group_by(A) %>%
   mutate(last = day[max(which(B>=1))])

或使用last中的dplyr函数(建议使用@docendo discimus)

df1 %>%
   group_by(A) %>%
   mutate(last= last(day[B>=1]))

关于第二个问题,

setDT(df1)[, dayafter:= if(all(!!B)) NA_integer_  else 
             day[max(which(B!=0))+1L] , A]
#    A B day dayafter
# 1: a 2   1        8
# 2: a 2   2        8
# 3: a 1   5        8
# 4: a 0   8        8
# 5: b 3   1        7
# 6: b 3   4        7
# 7: b 3   6        7
# 8: b 0   7        7
# 9: b 0   9        7
#10: c 1   2       NA
#11: c 1   3       NA
#12: c 1   4       NA

答案 1 :(得分:2)

这是一个不需要加载外部包的解决方案:

df <- structure(list(A = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L), .Label = c("a", "b", "c"), class = "factor"), 
B = c(2L, 2L, 1L, 0L, 3L, 3L, 3L, 0L, 0L, 1L, 1L, 1L), day = c(1L, 
2L, 5L, 8L, 1L, 4L, 6L, 7L, 9L, 2L, 3L, 4L)), .Names = c("A", 
"B", "day"), class = "data.frame", row.names = c(NA, -12L))

x <- split(df, df$A, drop = TRUE)

tp <- lapply(x, function(k) {
  tmp <- k[k$B >0,]
  k$last <- tmp$day[length(tmp$day)]
  k
})

do.call(rbind, tp)

         A B day last
#a.1  a 2   1    5
#a.2  a 2   2    5
#a.3  a 1   5    5
#a.4  a 0   8    5
#b.5  b 3   1    6
#b.6  b 3   4    6
#b.7  b 3   6    6
#b.8  b 0   7    6
#b.9  b 0   9    6
#c.10 c 1   2    4
#c.11 c 1   3    4
#c.12 c 1   4    4