满足条件时的子集值

时间:2017-01-10 01:01:42

标签: r subset

我有一个数据框,用于保存随机事件发生的次数。我想要的是,当第一种情况发生时,将第二种情况进行分组。或者'显示'出现在“事件”下,并结合“踢”和#39;或'键入'出现在事件2下。因此,在这种情况下,' place run'即使'放置'也不会满足条件。确实出现在'事件'。当我说第一种情况时,我只想要第一种情况,当这些选项中的任何一种在时间重置为0之前发生。因此对于第一段,我想要的输出是27,因为这是第一次当条件得到满足。对于第二段,我希望16.对于最后一段,输出将是41.(我已经将星号放在符合条件的行周围,因此很容易找到它们。这实际上并非如此存在于数据中。)

Time Event  Event 2
 0   Begin   NA
 23  place   run
 27  *Show   Type*
 34  *place  kick*
 41  good    bye
 42  *place  kick*
 0   Begin   NA
 11  Hat     Yellow
 13  Show    Green
 16  *place  kick*
 20  place   hit
 29  sign    redeem
 35  *Show   Type*
 0   Begin   NA
 5   Cream   Glue
 17  Show    Green
 18  Orange  Screen
 30  place   hit
 33  sign    redeem
 41  *Show   Type*
  0  Begin   NA
 ...

编辑:到目前为止,我能够做的是使用以下代码对具有“显示类型”或“踢”的行进行子集化:

Rows <- Data[(Data[,'Event'] == 'Show' & Data[,'Event 2']== 'Type') |
                  (Data[,'Event'] == 'place' & Data[,'Event 2']== 'kick' ),]

在我努力的地方,能够在时间重置为0后重置搜索这些值。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

& - infix-function可以用which函数包装,以生成满足这些条件的行号向量。然后使用[1]关注第一个。

df[ which(df[ , 'Event'] %in% c('place','Show') & df[ ,'Event.2'] %in% c('kick','Type') )[1], ]

请注意,我没有在Event2之间留一个空格,因为这会被R解析为两个不同的符号。所有make.names函数都使用read.*函数从列名中删除无效标点符号。

要在每个新段重置此过程,您可能会使用类似segvec= cumsum(df$Time==0)的内容构建段向量,然后可能使用split-apply-combine方法在结果子集中获取值。 / p>

一些轻微的测试代码:

 lapply( split(dat, cumsum(dat[ ,'Time']==0)), 
      function(df){df[ which(df[ ,'Event'] %in% c('place','Show') & 
                             df[ ,'Event.2'] %in% c('kick','Type') )[1], ]})
#------
$`1`
  Time Event Event.2
3   27  Show    Type

$`2`
   Time Event Event.2
10   16 place    kick

$`3`
   Time Event Event.2
20   41  Show    Type

dput(dat)
structure(list(Time = c(0L, 23L, 27L, 34L, 41L, 42L, 0L, 11L, 
13L, 16L, 20L, 29L, 35L, 0L, 5L, 17L, 18L, 30L, 33L, 41L), Event = structure(c(1L, 
6L, 7L, 6L, 3L, 6L, 1L, 4L, 7L, 6L, 6L, 8L, 7L, 1L, 2L, 7L, 5L, 
6L, 8L, 7L), .Label = c("Begin", "Cream", "good", "Hat", "Orange", 
"place", "Show", "sign"), class = "factor"), Event.2 = structure(c(NA, 
7L, 9L, 5L, 1L, 5L, NA, 10L, 3L, 5L, 4L, 6L, 9L, NA, 2L, 3L, 
8L, 4L, 6L, 9L), .Label = c("bye", "Glue", "Green", "hit", "kick", 
"redeem", "run", "Screen", "Type", "Yellow"), class = "factor")), .Names = c("Time", 
"Event", "Event.2"), class = "data.frame", row.names = c(NA, 
-20L))

答案 1 :(得分:0)

与42-'s相比,更为简洁(并且不那么优化),但是:

library(stringi)

read.table(text="Time Event  Event2
 0   Begin   NA
 23  place   run)
 27  *Show   Type*
 34  (*place  kic)k*
 41  good    bye
 42  (*place  kic)k*
 0   Begin   NA
 11  Hat     Yellow
 13  Show    Green
 16  *place  kick*
 20  place   hit
 29  sign    redeem
 35  *Show   Type*
 0   Begin   NA
 5   Cream   Glue
 17  Show    Green
 18  Orange  Screen
 30  place   hit
 33  sign    redeem
 41  *Show   Type*
  0  Begin   NA", header=TRUE, stringsAsFactors=FALSE) -> df

library(dplyr)

df$grp <- 0
df[which(df$Time == 0),]$grp <- 1
df$grp <- cumsum(df$grp)

group_by(df, grp) %>%
  filter(grepl("place|show", Event, ignore.case=TRUE) & grepl("kick|type", Event2, ignore.case=TRUE)) %>%
  slice(1) %>%
  select(-grp)
## Source: local data frame [3 x 4]
## Groups: grp [3]
## 
##     grp  Time  Event Event2
##   <dbl> <int>  <chr>  <chr>
## 1     1    27  *Show  Type*
## 2     2    16 *place  kick*
## 3     3    41  *Show  Type*