在R中,我如何向下填充与一个变量匹配但与另一变量不匹配的所有行

基兰·英格拉姆

我在其他地方找不到这个答案,如果真的很抱歉,请指出正确的方向

我想测试一个大型数据集(因此没有循环),对于所有匹配一个变量的行(例如ID),然后测试第二个变量(例如Time)是否在2小时内。我想通过结合ID和时间来制作一个URN。

如果时间在2小时以内(小于或等于),我想使用与原始第一行相同的ID。

对于时差大于2小时的所有行,我想从此点开始创建新的URN。

使用数据可能更有意义:

ID      Time      URN             URN_whichIwanttomake  Index
hawk    09:05     hawk_09         hawk_09               1
hawk    09:10     hawk_09         hawk_09               2
hawk    10:00     hawk_10         hawk_09               3
hawk    11:00     hawk_11         hawk_09               4
hawk    15:00     hawk_15         hawk_15               5
hawk    16:00     hawk_16         hawk_15               6
eagle   12:00     eagle_12        eagle_12              7
eagle   12:20     eagle_12        eagle_12              8
eagle   12:45     eagle_12        eagle_12              9
eagle   13:50     eagle_13        eagle_12              10
eagle   14:00     eagle_14        eagle_12              11
eagle   14:30     eagle_14        eagle_14              12
eagle   15:15     eagle_15        eagle_14              13

我尝试在if语句中将向量与逻辑语句一起使用,我可以使我的逻辑正常工作并返回TRUE / FALSE的正确向量,但是我不能使用它来覆盖URN

到目前为止,我的代码:

IndexShiftedBy1 <- dt$Index + 1               # ie a vector which starts at 2 and goes up to 14

if ((dt$ID[dt$Index] == dt$ID[IndexShiftedBy1]) # ie if the two IDs are the same
&  (dt$URN[dt$Index] != dt$URN[IndexShiftedBy1])) { # URN2 (ie time dependent) is NOT the same
dt$URN[IndexShiftedBy1] <- dt$URN[Index] } # overwrite lower row with upper row's value

现在,首先这是行不通的,其次,如果这样做了,那么我将不得不多次运行它,因为它将问题连续下移了!

非常感谢您提供的任何帮助,我显然缺少有用的功能/需要自己编写一个功能,但这超出了我的知识水平

r2evans

这是一个整洁的解决方案。关键组成部分是zoo::na.locf(不是tidyverse),它NA用先前的非NA填充

library(dplyr)
# library(zoo)
dat %>%
  group_by(ID) %>%
  mutate(
    URN_new = if_else(c(TRUE, `units<-`(diff(Time), "hours") > 2), URN_original, NA_character_),
    URN_new = zoo::na.locf(URN_new)
  ) %>%
  ungroup()
# # A tibble: 13 x 5
#    ID    Time                URN_original URN_whichIwanttomake URN_new 
#    <chr> <dttm>              <chr>        <chr>                <chr>   
#  1 hawk  2018-10-26 09:05:00 hawk_09      hawk_09              hawk_09 
#  2 hawk  2018-10-26 09:10:00 hawk_09      hawk_09              hawk_09 
#  3 hawk  2018-10-26 10:00:00 hawk_10      hawk_09              hawk_09 
#  4 hawk  2018-10-26 11:00:00 hawk_11      hawk_09              hawk_09 
#  5 hawk  2018-10-26 15:00:00 hawk_15      hawk_15              hawk_15 
#  6 hawk  2018-10-26 16:00:00 hawk_16      hawk_15              hawk_15 
#  7 eagle 2018-10-26 12:00:00 eagle_12     eagle_12             eagle_12
#  8 eagle 2018-10-26 12:20:00 eagle_12     eagle_12             eagle_12
#  9 eagle 2018-10-26 12:45:00 eagle_12     eagle_12             eagle_12
# 10 eagle 2018-10-26 13:50:00 eagle_13     eagle_12             eagle_12
# 11 eagle 2018-10-26 14:00:00 eagle_14     eagle_12             eagle_12
# 12 eagle 2018-10-26 14:30:00 eagle_14     eagle_14             eagle_12
# 13 eagle 2018-10-26 15:15:00 eagle_15     eagle_14             eagle_12

data.table 替代方案:

library(data.table)
datdt <- as.data.table(dat)
datdt[,
      URN_newdt := zoo::na.locf(
        ifelse(c(TRUE, `units<-`(diff(Time), "hours") > 2), URN_original, NA_character_)
      ),
      by = "ID"]

基数R:

ave(dat, dat$ID, FUN = function(d) {
  d$URN_newave <- zoo::na.locf(
    ifelse(c(TRUE, `units<-`(diff(d$Time), "hours") > 2), d$URN_original, NA_character_)
  )
  d
})

简要说明:zoo::na.locfNA最近的非NA填充

zoo::na.locf(c("hawk_09", NA, NA, NA, "hawk_15", NA))
# [1] "hawk_09" "hawk_09" "hawk_09" "hawk_09" "hawk_15" "hawk_15"

知道这一点,下一步就是弄清楚NA当时间差小于两个小时时如何分配给新的URN。diff(dat$Time)是足够直接的,尽管因为它可以在不发出警告的情况下返回不同的单位,所以我们需要将其封装起来units<-(..., "hours")以确保获得所需的东西。

下一步,diff返回向量长度减去1,因此我们需要确定是否需要添加前缀或附加元素,并且该附加值应为TRUE还是FALSE在这种情况下,我们总是希望组中的第一个成为原始组,因此前置TRUE是最有意义的。


数据:

dat <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
ID      Time      URN_original    URN_whichIwanttomake
hawk    09:05     hawk_09         hawk_09
hawk    09:10     hawk_09         hawk_09
hawk    10:00     hawk_10         hawk_09
hawk    11:00     hawk_11         hawk_09 
hawk    15:00     hawk_15         hawk_15
hawk    16:00     hawk_16         hawk_15
eagle   12:00     eagle_12        eagle_12
eagle   12:20     eagle_12        eagle_12
eagle   12:45     eagle_12        eagle_12
eagle   13:50     eagle_13        eagle_12
eagle   14:00     eagle_14        eagle_12
eagle   14:30     eagle_14        eagle_14
eagle   15:15     eagle_15        eagle_14")
dat$Time <- as.POSIXct(paste(Sys.Date(), dat$Time))

POSIXt为了方便起见,我使用“今天” 我建议您使用类似的东西POSIXt,但要由您决定时间的差异。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

对于R中的循环-删除由一个变量匹配的所有行

如何从矩阵中删除与另一个向量中的值匹配的所有行?

删除列中的值与另一个数据集中的列中的值不匹配的所有行

如何对同一变量中的所有值求和?

我如何将 Url 存储在变量中并检查它是否与另一个 url 匹配

有没有一种方法可以通过存储在R中另一个DataFrame中的唯一变量来过滤DataFrame

按组匹配另一个变量的第一行的变量的值

创建由R中的另一个变量分组的变量的所有值的列表

如果另一个变量中的值在dplyr中的列表中不匹配,则擦除一个变量中的值

使用SUMIFS对与另一条件匹配的列中与一个条件匹配的所有行求和

从另一个文件中删除文件中与文本不匹配的所有行

查找另一个工作表匹配键中的所有行

SQL:选择与另一个表中的内容匹配的所有行

如何用所有列的另一个数据框中的匹配行替换一个数据框中的行

如何保留与另一个数据集的一个col匹配的变量

如何从与另一个表中的所有值匹配的表中获取记录

如何使用grep / awk / unix将一个文件中的所有行匹配到另一个文件中,即使它们是重复的

打印与我的模式匹配的所有行,直到最后一个模式匹配

在R中,将一个数据集中的变量与另一个数据集中的匹配变量进行装箱

如果第一列与另一个工作表上的值匹配,如何返回一行中的所有单元格

如何选择另一个表中没有匹配条目的行?

在数据框中使用现有变量名称创建一个新变量,在匹配每个变量列表中的非 NA 值时填充它

引用R中同一变量中的前一个值,无循环

如何制作一个变量以显示R中另一个变量的差异?

如何从SAS数据集中选择与另一SAS数据集中的至少一个值匹配的所有行

在 R 中,如何从另一个数据框中的一个数据框中选择所有变量?

将表中的值(行)添加到另一个仅用于匹配变量

如何从一个表中删除与另一个表匹配的行?

如何查询具有一个匹配项和一个不匹配项的行