简体   繁体   中英

creating new columns using nested subsets of rows in R

I want to create 2 new columns in a data frame based on already existing columns in a data frame. I use dplyr fairly often by still struggle with recoding for nested cases, particularly when the case isn't binary.

The existing data frame has a time sequence (to index observations), a set of states from 1:3, and a factor for each a == 2:

    time <- seq(as.POSIXlt(Sys.time(), "GMT"), by="min", length.out = 25)
    a <- c(rep(1,10),rep(2,5),rep(3,6),rep(2,4))
    b <- c(rep(NA,10),rep("LAND",3),rep("WATER",2),rep(NA,6),rep("LAND",4))
    data <- data.frame(time,a,b)

                  time a     b
1  2019-02-12 23:18:36 1  <NA>
2  2019-02-12 23:19:36 1  <NA>
3  2019-02-12 23:20:36 1  <NA>
4  2019-02-12 23:21:36 1  <NA>
5  2019-02-12 23:22:36 1  <NA>
6  2019-02-12 23:23:36 1  <NA>
7  2019-02-12 23:24:36 1  <NA>
8  2019-02-12 23:25:36 1  <NA>
9  2019-02-12 23:26:36 1  <NA>
10 2019-02-12 23:27:36 1  <NA>
11 2019-02-12 23:28:36 2  LAND
12 2019-02-12 23:29:36 2  LAND
13 2019-02-12 23:30:36 2  LAND
14 2019-02-12 23:31:36 2 WATER
15 2019-02-12 23:32:36 2 WATER
16 2019-02-12 23:33:36 3  <NA>
17 2019-02-12 23:34:36 3  <NA>
18 2019-02-12 23:35:36 3  <NA>
19 2019-02-12 23:36:36 3  <NA>
20 2019-02-12 23:37:36 3  <NA>
21 2019-02-12 23:38:36 3  <NA>
22 2019-02-12 23:39:36 2  LAND
23 2019-02-12 23:40:36 2  LAND
24 2019-02-12 23:41:36 2  LAND
25 2019-02-12 23:42:36 2  LAND

I want to (1) sequence the event number for each row ("event"), such that continuous sequences of a == 2 are a single event, and (2) create a new column ("eventtype") within each event such that:

  • if all b within an event is the same (eg, all rows are either "LAND" or "WATER"), code "LAND" or "WATER";

  • but is "MIXED" if the event includes both "LAND" and "WATER" observations.

The resulting df would look like this:

   time                a  b       event   eventtype
1  2019-02-12 22:51:31 1  <NA>    NA      <NA>
2  2019-02-12 22:52:31 1  <NA>    NA      <NA>
3  2019-02-12 22:53:31 1  <NA>    NA      <NA>
4  2019-02-12 22:54:31 1  <NA>    NA      <NA>
5  2019-02-12 22:55:31 1  <NA>    NA      <NA>
6  2019-02-12 22:56:31 1  <NA>    NA      <NA>
7  2019-02-12 22:57:31 1  <NA>    NA      <NA>
8  2019-02-12 22:58:31 1  <NA>    NA      <NA>
9  2019-02-12 22:59:31 1  <NA>    NA      <NA>
10 2019-02-12 23:00:31 1  <NA>    NA      <NA>
11 2019-02-12 23:01:31 2  LAND     1     MIXED
12 2019-02-12 23:02:31 2  LAND     1     MIXED
13 2019-02-12 23:03:31 2  LAND     1     MIXED
14 2019-02-12 23:04:31 2 WATER     1     MIXED
15 2019-02-12 23:05:31 2 WATER     1     MIXED
16 2019-02-12 23:06:31 3  <NA>    NA      <NA>
17 2019-02-12 23:07:31 3  <NA>    NA      <NA>
18 2019-02-12 23:08:31 3  <NA>    NA      <NA>
19 2019-02-12 23:09:31 3  <NA>    NA      <NA>
20 2019-02-12 23:10:31 3  <NA>    NA      <NA>
21 2019-02-12 23:11:31 3  <NA>    NA      <NA>
22 2019-02-12 23:12:31 2  LAND     2      LAND
23 2019-02-12 23:13:31 2  LAND     2      LAND
24 2019-02-12 23:14:31 2  LAND     2      LAND
25 2019-02-12 23:15:31 2  LAND     2      LAND

An answer using dplyr::mutate() or case_when() would be especially helpful.

Could do:

library(dplyr)

data %>%
  group_by(a) %>%
  mutate(rn = row_number()) %>%
  group_by(a, b) %>%
  mutate(rn = as.integer(rn != lag(rn) + 1),
         event = ifelse(is.na(b), NA, cumsum(replace(rn, is.na(rn), 0)) + 1)) %>%
  group_by(a, event) %>%
  mutate(eventtype = ifelse(n_distinct(b) > 1, "MIXED", as.character(b))) %>%
  select(-rn)

Output:

                  time a     b event eventtype
1  2019-02-12 23:31:48 1  <NA>    NA      <NA>
2  2019-02-12 23:32:48 1  <NA>    NA      <NA>
3  2019-02-12 23:33:48 1  <NA>    NA      <NA>
4  2019-02-12 23:34:48 1  <NA>    NA      <NA>
5  2019-02-12 23:35:48 1  <NA>    NA      <NA>
6  2019-02-12 23:36:48 1  <NA>    NA      <NA>
7  2019-02-12 23:37:48 1  <NA>    NA      <NA>
8  2019-02-12 23:38:48 1  <NA>    NA      <NA>
9  2019-02-12 23:39:48 1  <NA>    NA      <NA>
10 2019-02-12 23:40:48 1  <NA>    NA      <NA>
11 2019-02-12 23:41:48 2  LAND     1     MIXED
12 2019-02-12 23:42:48 2  LAND     1     MIXED
13 2019-02-12 23:43:48 2  LAND     1     MIXED
14 2019-02-12 23:44:48 2 WATER     1     MIXED
15 2019-02-12 23:45:48 2 WATER     1     MIXED
16 2019-02-12 23:46:48 3  <NA>    NA      <NA>
17 2019-02-12 23:47:48 3  <NA>    NA      <NA>
18 2019-02-12 23:48:48 3  <NA>    NA      <NA>
19 2019-02-12 23:49:48 3  <NA>    NA      <NA>
20 2019-02-12 23:50:48 3  <NA>    NA      <NA>
21 2019-02-12 23:51:48 3  <NA>    NA      <NA>
22 2019-02-12 23:52:48 2  LAND     2      LAND
23 2019-02-12 23:53:48 2  LAND     2      LAND
24 2019-02-12 23:54:48 2  LAND     2      LAND
25 2019-02-12 23:55:48 2  LAND     2      LAND

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM