变异以获取值前后的值

Mutate to obtain values before and after a value

我有一个数据集,其格式类似于:

amount | event
------ | ------
 3     |  FALSE
 4     |  FALSE
 6     |  TRUE
 7     |  FALSE
 3     |  FALSE
 4     |  TRUE
 8     |  FALSE

并希望根据 event 列的值进行拆分和变异,并创建新列,仅当 event 的值为行前后填充值时是真的。例如:

amount | event | before | after
------ | ----- | -----  | -----
 3     | FALSE |  NA    | NA
 4     | FALSE |  NA    | NA
 6     | TRUE  |  4     | 7
 7     | FALSE |  NA    | NA
 3     | FALSE |  NA    | NA
 4     | TRUE  |  3     | 8
 8     | FALSE |  NA    | NA

我正在考虑 ddplymutate,但不确定如何根据拆分后的偏移量访问值。有什么想法吗?

使用base R,我们用which('indx')在'event'列中找到TRUE值的位置,创建两个NA列( 'before' 和 'after'),然后我们将 'indx' 下面位置 1 和上面位置 1 的 'amount' 值分配给 'before' 和 'after'列

indx <- which(df1$event)
df1[c('before','after')] <- NA
df1$before[indx] <- df1$amount[indx-1]
df1$after[indx] <- df1$amount[indx+1]
 df1
 #  amount event before after
 #1      3 FALSE     NA    NA
 #2      4 FALSE     NA    NA
 #3      6  TRUE      4     7
 #4      7 FALSE     NA    NA
 #5      3 FALSE     NA    NA
 #6      4  TRUE      3     8
 #7      8 FALSE     NA    NA

或者使用data.table(类似于@Marat Talipov的想法),我们可以使用shift来获取'amount'的laglead值创建列 'before/after'。我们将 'event' (!event) 中 FALSE 值对应的那些列中的行更改为 NA。

 library(data.table)#data.table_1.9.5
 setDT(df1)[,c('before', 'after'):= list(shift(amount, type='lag'),
    shift(amount, type='lead')) ][(!event), 3:4 := NA][]
 #     amount event before after
 #1:      3 FALSE     NA    NA
 #2:      4 FALSE     NA    NA
 #3:      6  TRUE      4     7
 #4:      7 FALSE     NA    NA
 #5:      3 FALSE     NA    NA
 #6:      4  TRUE      3     8
 #7:      8 FALSE     NA    NA

数据

df1 <- structure(list(amount = c(3L, 4L, 6L, 7L, 3L, 4L, 8L), 
event = c(FALSE, 
FALSE, TRUE, FALSE, FALSE, TRUE, FALSE)), .Names = c("amount", 
"event"), class = "data.frame", row.names = c(NA, -7L))

您可以使用此代码:

library(dplyr)

d %>% 
  mutate(before=ifelse(event,lag(amount),NA),
         after =ifelse(event,lead(amount),NA))

#  amount event before after
#1      3 FALSE     NA    NA
#2      4 FALSE     NA    NA
#3      6  TRUE      4     7
#4      7 FALSE     NA    NA
#5      3 FALSE     NA    NA
#6      4  TRUE      3     8
#7      8 FALSE     NA    NA

其中 d 是您的示例数据集:

d <- structure(list(amount = c(3, 4, 6, 7, 3, 4, 8), event = c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE)), .Names = c("amount", "event"), row.names = c(NA, -7L), class = "data.frame")

数据

df1 <- structure(list(smp = 1:17, x = c(609, 609, 609, 625, 625, 608, 608, 608, 608, 608, 608, 608, 630, 631, 605, 603, 602), y = c(449, 446, 446, 460, 455, 445, 445, 445, 445, 445, 445, 445, 459, 459, 446, 448, 452), blink = c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE)), .Names = c("smp", "x", "y", "blink"), class = "data.frame", row.names = c(NA, -17L))

在这个有多个 TRUE 值的数据实例中,可能需要采用不同的方法来建立索引以获取感兴趣条件前后的实际值,因为上述基本方法将 return 内的值感兴趣的条件。

考虑在条件前后需要 SpatialPoints,然后想比较给定点之前的距离和给定点之后的条件。在那种情况下,您想要(恰好)在条件之前和(恰好)之后的点,并且可能不想要中间点。类似于上面 akrun 的回答,这建议同时调整左侧 (LHS) 和右侧 (RHS) 的索引。调整 LHS 和 RHS 的索引提供了对 'outsideness' 感兴趣的条件(之前或之后)的第二次逻辑测试的机会,在有多个 T 的情况下,上述方法没有解决在 F 之后跟一个 F,即 F、T、T、T、F、F。

head(df1, n = 17) smp x y blink 1 1 609 449 FALSE 2 2 609 446 FALSE 3 3 609 446 TRUE 4 4 625 460 FALSE 5 5 625 455 FALSE 6 6 608 445 TRUE 7 7 608 445 TRUE 8 8 608 445 FALSE 9 9 608 445 FALSE 10 10 608 445 TRUE 11 11 608 445 TRUE 12 12 608 445 TRUE 13 13 630 459 FALSE 14 14 631 459 FALSE 15 15 605 446 TRUE 16 16 603 448 TRUE 17 17 602 452 FALSE

df1[c('pre_x', 'pre_y', 'post_x', 'post_y')] <- NA

在这种情况下,pre_x/pre_y、post_x/post_y 最终将是 cbind 坐标,然后是 SpatialPoints;但是,这是在确定之前和之后的内容之后发生的。您的用例可能不同,但逻辑应该成立。

indx_1 <- which(df1$blink)

indx_1 [1] 3 6 7 10 11 12 15 16

然后用indx_1计算pre_x,pre_y,post_x,post_y:

df1$pre_x[indx_1 - 1] <- df1$x[indx_1 - 1] df1$pre_y[indx_1 - 1] <- df1$y[indx_1 - 1] df1$post_x[indx_1 + 1] <- df1$post_x[indx_1 + 1] df1$post_y[indx_1 + 1] <- df1$post_y[indx_1 + 1]

> head(df1, n = 17) smp x y blink pre_x pre_y post_x post_y 1 1 609 449 FALSE NA NA NA NA 2 2 609 446 FALSE 609 446 NA NA 3 3 609 446 TRUE NA NA NA NA 4 4 625 460 FALSE NA NA 625 460 5 5 625 455 FALSE 625 455 NA NA 6 6 608 445 TRUE 608 445 NA NA 7 7 608 445 TRUE NA NA 608 445 8 8 608 445 FALSE NA NA 608 445 9 9 608 445 FALSE 608 445 NA NA 10 10 608 445 TRUE 608 445 NA NA 11 11 608 445 TRUE 608 445 608 445 12 12 608 445 TRUE NA NA 608 445 13 13 630 459 FALSE NA NA 630 459 14 14 631 459 FALSE 631 459 NA NA 15 15 605 446 TRUE 605 446 NA NA 16 16 603 448 TRUE NA NA 603 448 17 17 602 452 FALSE NA NA 602 452

现在所需的值写在感兴趣的条件之外 并可靠地报告前后值。此外, a before index (indx_2) and after (indx_3) 可用于 select 进行进一步处理,在我的例子中为 SpatialPoints.

制作坐标

indx_2 <- which(!df1$blink & !is.na(df1$pre_x))

indx_3 <- which(!df1$blink & !is.na(df1$post_x))

coords_pre <- cbind(x = df1$pre_x[indx_2], y = df1$pre_y[indx_2])

coords_post <- cbind( x = df1$post_x[indx_3], y = df1$post_y[indx_3])

library(sp) pre_blink_sp <- SpatialPoints(coords_pre) > summary(pre_blink_sp) Object of class SpatialPoints Coordinates: min max x 608 631 y 445 459 Is projected: NA proj4string : [NA] Number of points: 4

已经弄清楚如何在 base 中执行此操作,尽管很单调,df1$smp 有没有 setkey() 因为我现在试图弄清楚如何在 data.table 中完成同样的事情。