在R中有条件地提取特定行的分组项目

时间:2015-03-25 21:46:38

标签: r

我有下面的数据集,它代表了我正在使用的更大的数据集。下面的数据集有3列:'weight','feed'和'flag'。权重是一个数值,饲料是一个因子变量,而标志是我的指标变量。 Flag的值为0,1或2(最终将是随机的,但请使用下面提供的值)。

对于'feed'字段中的哪个因子类别,我想检查'flag'字段。如果'flag'值= 2&对于该值2的第一次出现,我想为该Feed类别接下来连续2行 - 如果在特定Feed类的最后一行中出现2,则没有任何事情发生

例如,数据帧的第2行,其中horsebean = 160,标志值为2.我将标记第3行& 4因为这是接下来的两行,其中出现了蚕豆的值2。我需要小心,但是如果在第9行或第10行之前没有发生蚕豆标志值2 - 我不想不小心从亚麻籽中选择行。

理想情况下,会创建第4列,其中包含某种标记,表示它们是标记值为2的行。

如果有人能帮助我制定或解决这个问题,我将永远感激不尽。

df =    structure(list(weight = c(179, 160, 136, 227, 217, 168, 108, 
  124, 143, 140, 309, 229, 181, 141, 260, 203, 148, 169, 213, 257, 
  244, 271, 243, 230, 248, 327, 329, 250, 193, 271, 316, 267, 199, 
 171, 158, 248, 423, 340, 392, 339, 341, 226, 320, 295, 334, 322, 
 297, 318, 325, 257, 303, 315, 380, 153, 263, 242, 206, 344, 258, 
368, 390, 379, 260, 404, 318, 352, 359, 216, 222, 283, 332), 
feed = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L), .Label = c("casein", "horsebean", "linseed", "meatmeal", 
"soybean", "sunflower"), class = "factor"), flag = structure(c(2L, 
3L, 3L, 3L, 3L, 1L, 2L, 2L, 2L, 1L, 1L, 3L, 2L, 3L, 2L, 3L, 
3L, 1L, 2L, 3L, 1L, 2L, 2L, 1L, 2L, 3L, 2L, 3L, 2L, 2L, 2L, 
3L, 3L, 1L, 2L, 1L, 1L, 3L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 2L, 
2L, 3L, 3L, 3L, 2L, 3L, 2L, 2L, 3L, 3L, 3L, 2L, 2L, 3L, 3L, 
1L, 3L, 1L, 2L, 3L, 3L, 3L, 1L, 1L, 2L), .Label = c("0", 
"1", "2"), class = "factor")), .Names = c("weight", "feed", 
 "flag"), row.names = c(NA, -71L), class = "data.frame")

还假设随机生成标志值,并且对于每个分组值可能出现或可能不出现标志值2。例如,如果

  df$flag = sample(c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), replace=T, size=nrow(df))

1 个答案:

答案 0 :(得分:3)

这是一个简单的data.table解决方案

library(data.table)
indx <- setDT(df)[, .I[match(2, flag) + seq_len(2)], by = feed]$V1
df[indx, flag2 := 1][]
#     weight      feed flag flag2
#  1:    179 horsebean    1    NA
#  2:    160 horsebean    2    NA
#  3:    136 horsebean    2     1
#  4:    227 horsebean    2     1
#  5:    217 horsebean    2    NA
#  6:    168 horsebean    0    NA
#  7:    108 horsebean    1    NA
#  8:    124 horsebean    1    NA
#  9:    143 horsebean    1    NA
# 10:    140 horsebean    0    NA
# ...

为什么这会起作用?因为我们使用match来匹配每个组中2(索引)中的第一个 .I。因此,如果索引超过某个组的大小,它将返回NA。最终index只是我们想要选择的行的索引。因此,在通过此索引进行子设置时,我们将分配一个新标志,该标志将告诉我们想要哪些行。

例如,如果您只想选择flag2中的行,只需使用na.omit列中的flag2

na.omit(df, "flag2")
#     weight      feed flag flag2
#  1:    136 horsebean    2     1
#  2:    227 horsebean    2     1
#  3:    181   linseed    1     1
#  4:    141   linseed    2     1
#  5:    329   soybean    1     1
#  6:    250   soybean    2     1
#  7:    392 sunflower    1     1
#  8:    339 sunflower    1     1
#  9:    257  meatmeal    2     1
# 10:    303  meatmeal    1     1
# 11:    390    casein    2     1
# 12:    379    casein    0     1