R 在不同列中满足条件后出现的子集行

R 在不同列中满足条件后出现的子集行,r,subset,R,Subset,我到处寻找,似乎不知道如何解决这个问题 我有一个主题的数据集,我想在一个不同的列中发生的事件之后对所有行进行子集。以下是数据集外观的示例: subject <- letters[rep(seq(from = 1, to = 5), each = 10)] value1 <- rnorm(n = length(subject), mean = 20, sd = 5) value2 <- rnorm(n = length(subject), mean = 30, sd = 10)

我到处寻找,似乎不知道如何解决这个问题

我有一个主题的数据集,我想在一个不同的列中发生的事件之后对所有行进行子集。以下是数据集外观的示例:

subject <- letters[rep(seq(from = 1, to = 5), each = 10)]
value1 <- rnorm(n = length(subject), mean = 20, sd = 5)
value2 <- rnorm(n = length(subject), mean = 30, sd = 10)
tag <- rep(NA, n = length(subject))
df <- data.frame(subject, value1, value2, tag)

# add random events

df[6,4] <- "event"
df[16,4] <- "event"
df[24,4] <- "event"
df[39,4] <- "event"
df[43,4] <- "event"

head(df, 20)
   subject   value1   value2   tag
1        a 29.48322 28.50112  <NA>
2        a 26.83034 32.61494  <NA>
3        a 19.03148 38.66233  <NA>
4        a 19.97549 36.09613  <NA>
5        a 22.04944 26.80911  <NA>
6        a 16.67589 37.07147 event
7        a 14.25538 32.94055  <NA>
8        a 18.29705 24.17948  <NA>
9        a 14.26047 23.94956  <NA>
10       a 23.91977 39.76018  <NA>
11       b 20.64587 38.93593  <NA>
12       b 20.72713 14.29013  <NA>
13       b 17.55487 27.63619  <NA>
14       b 14.18344 40.30682  <NA>
15       b 11.47055 22.01550  <NA>
16       b 24.60832 38.49901 event
17       b 15.10552 32.08878  <NA>
18       b 23.21466 28.17392  <NA>
19       b 20.59442 34.18078  <NA>
20       b 21.19128 33.50000  <NA>

subject是的,在base R中这是一个简单的解决方案:

indx <- unlist(lapply(which(df$tag == "event"), "+", 0:1))
df[indx, ]
#   subject    value1   value2   tag
#6        a 25.996706 15.65917 event
#7        a 20.336984 35.03734  <NA>
#16       b  9.825914 25.34336 event
#17       b 24.344257 30.15755  <NA>
#24       c 18.586266 33.82119 event
#25       c 25.879272 52.43784  <NA>
#39       d 24.366653 25.03767 event
#40       d 19.870183 36.61909  <NA>
#43       e 23.706029 43.46765 event
#44       e 15.091674 29.45431  <NA>
这些标记的顺序不同,但人们总是可以对它们进行排序

要按主题解决此问题,您可以检查添加一个是否将其保留在主题内,如果没有,则排除:

eindx <- which(df$tag == "event")
not_eq <- which(df$subject[eindx] != df$subject[eindx+1])
indx <- sort(c(eindx, setdiff(eindx, not_eq) + 1))
df[indx, ]


res是的,这是一个简单的解决方案:

indx <- unlist(lapply(which(df$tag == "event"), "+", 0:1))
df[indx, ]
#   subject    value1   value2   tag
#6        a 25.996706 15.65917 event
#7        a 20.336984 35.03734  <NA>
#16       b  9.825914 25.34336 event
#17       b 24.344257 30.15755  <NA>
#24       c 18.586266 33.82119 event
#25       c 25.879272 52.43784  <NA>
#39       d 24.366653 25.03767 event
#40       d 19.870183 36.61909  <NA>
#43       e 23.706029 43.46765 event
#44       e 15.091674 29.45431  <NA>
这些标记的顺序不同,但人们总是可以对它们进行排序

要按主题解决此问题,您可以检查添加一个是否将其保留在主题内,如果没有,则排除:

eindx <- which(df$tag == "event")
not_eq <- which(df$subject[eindx] != df$subject[eindx+1])
indx <- sort(c(eindx, setdiff(eindx, not_eq) + 1))
df[indx, ]


res根据子集之后要执行的操作,这可能会起作用:

library(tidyverse)

df %>%
  group_by(subject) %>%
  mutate(event_grp = cumsum(!is.na(tag))) %>%
  group_by(subject, event_grp) %>%
  summarise(
    avg_val1 = mean(value1),
    avg_val2 = mean(value2)
  )

#    subject event_grp avg_val1 avg_val2
#    <fct>       <int>    <dbl>    <dbl>
#  1 a               0     22.7     38.6
#  2 a               1     20.5     30.5
#  3 b               0     21.1     25.0
#  4 b               1     21.4     21.2
#  5 c               0     19.5     35.8
#  6 c               1     18.6     23.9
#  7 d               0     18.7     31.1
#  8 d               1     19.4     42.0
#  9 e               0     18.5     25.7
# 10 e               1     20.7     30.2

根据子集之后要执行的操作,这可能会起作用:

library(tidyverse)

df %>%
  group_by(subject) %>%
  mutate(event_grp = cumsum(!is.na(tag))) %>%
  group_by(subject, event_grp) %>%
  summarise(
    avg_val1 = mean(value1),
    avg_val2 = mean(value2)
  )

#    subject event_grp avg_val1 avg_val2
#    <fct>       <int>    <dbl>    <dbl>
#  1 a               0     22.7     38.6
#  2 a               1     20.5     30.5
#  3 b               0     21.1     25.0
#  4 b               1     21.4     21.2
#  5 c               0     19.5     35.8
#  6 c               1     18.6     23.9
#  7 d               0     18.7     31.1
#  8 d               1     19.4     42.0
#  9 e               0     18.5     25.7
# 10 e               1     20.7     30.2

很好的方法,但我认为这个问题是针对活动后的所有行和主题提出的。也许
ave()
by()
?@JasonAizkalns是的,你是对的。我读得太快了。我现在编辑了这篇文章。通过更巧妙地使用索引,并在添加1时检查我们是否保留在一个主题内,您仍然可以解决此问题,而无需借助于
拆分
ave
等。无论如何,tidyr方法当然总是优雅的,正如你所展示的。很好的方法,但我认为这个问题是在活动结束后按主题问所有行的。也许
ave()
by()
?@JasonAizkalns是的,你是对的。我读得太快了。我现在编辑了这篇文章。通过更巧妙地使用索引,并在添加1时检查我们是否保留在一个主题内,您仍然可以解决此问题,而无需借助于
拆分
ave
等。无论如何,tidyr方法当然总是优雅的,正如您所展示的那样。
df %>%
  group_by(subject) %>%
  mutate(event_grp = cumsum(!is.na(tag))) %>%
  filter(event_grp >= 1)