【问题标题】:Ordered values - select first instance of lowest value, then first instance of next lowest subsequent value and so on有序值 - 选择最低值的第一个实例,然后选择下一个最低后续值的第一个实例,依此类推
【发布时间】:2015-08-27 04:04:13
【问题描述】:

我有一个包含许多不同 UniqueID 的数据框,它们也按日期排序。每个 UniqueID 从最旧日期到最新日期排序。我们还有一个名为 steps 的列,从 1 到 4 排序。

每个 UniqueID 的目标是查找第一个步骤的最旧实例,然后是第二个步骤的最旧实例,等等。某些步骤可能丢失,例如 UniqueID = "B" 的第 3 步丢失。在这种情况下,我们跳过第 3 步,继续第 4 步。

这是原始数据框。

   UniqueID       Date Step
1         A 2015-07-03    2
2         A 2015-07-07    3
3         A 2015-07-09    1
4         A 2015-07-14    4
5         A 2015-07-17    1
6         A 2015-07-20    2
7         A 2015-07-23    2
8         A 2015-07-24    3
9         A 2015-07-29    3
10        B 2015-06-01    3
11        B 2015-06-15    2
12        B 2015-06-22    1
13        B 2015-06-29    4
14        B 2015-07-13    2
15        B 2015-06-22    2
16        B 2015-07-08    2
17        B 2015-07-27    4

我们要选择的有效条目是观察 3、6、8、12、14、17。创建此数据框:

 UniqueID       Date Step
3         A 2015-07-09    1
6         A 2015-07-20    2
8         A 2015-07-24    3
12        B 2015-06-22    1
14        B 2015-07-13    2
17        B 2015-07-27    4

我有逻辑和一些伪代码,但无法将它们放在一起。因此,在 UniqueID = "A" 的示例数据帧中,我们首先将数据帧分组:

group_by(UniqueID)

找到 UniqueID = "A" 的最小值并赋值给一个变量。

v <- min(Step)returns 1

然后为这一步取索引

i <- which.min(Step) 返回 3

然后我们想要找到大于第一步的最小步长,并且只搜索出现在第一步之后的元素。所以现在我们只搜索 > 1 的 Step 值,并且只从我们找到的第一个值的位置开始,在这种情况下从观察 3 开始。我们希望对每个 UniqueID 的所有观察重复此操作,直到我们到达最后一个观测值,或者在剩余元素中找不到大于最后一个观测值的观测值。

这是用于创建示例数据框的 dput:

structure(list(UniqueID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A", 
"B"), class = "factor"), Date = structure(c(16619, 16623, 16625, 
16630, 16633, 16636, 16639, 16640, 16645, 16587, 16601, 16608, 
16615, 16629, 16608, 16624, 16643), class = "Date"), Step = c(2, 
3, 1, 4, 1, 2, 2, 3, 3, 3, 2, 1, 4, 2, 2, 2, 4)), .Names = c("UniqueID", 
"Date", "Step"), row.names = c(NA, -17L), class = "data.frame")

使用 jeremycg 的方法崩溃的替代 dput。

structure(list(UniqueID = structure(c(1L, 1L, 1L, 1L, 1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 8L, 8L, 9L, 9L, 10L, 11L), .Label = c("A","B",
"C","D","E","F","G","H","I","J","K"),
class = "factor"), Date = c("3/08/2015", 
"21/07/2015", "7/07/2015", "7/07/2015", "29/07/2015", "29/07/2015", 
"29/06/2015", "13/07/2015", "9/07/2015", "29/07/2015", "24/07/2015", 
"2/07/2015", "16/07/2015", "18/06/2015", "8/07/2015", "29/07/2015", 
"12/06/2015", "27/07/2015"), Step = c(1, 1, 4, 4, 4, 3, 
5, 5, 1, 4, 1, 2, 2, 2, 3, 3, 2, 2)), .Names = c("UniqueID", 
"Date", "Step"), class = c("tbl_df", "data.frame"
), row.names = c(NA, -18L))

编辑:即使使用来自 jeremycg 的更新代码,UniqueID 的 dput 也会继续崩溃:

structure(list(UniqueID = structure(c(1L, 1L, 1L, 1L, 1L, 1L ), .Label = c("A"                                                                                              ), class = "factor"), Date = structure(c(16619, 16623, 16625,                                                                                                                                          16630, 16633, 16636), class = "Date"), Step = c(1, 5, 5, 1, 1, 1)), .Names = c("UniqueID",                                                                                                                                                                                                                                               "Date", "Step"), row.names = c(NA, -6L), class = "data.frame")

【问题讨论】:

  • 您能解释一下吗?我不明白你是如何设法获得输出数据框的。最旧的条目是什么意思?
  • @RonakShah 条目按“日期”列从最旧到最新排序。因此,要获得第一个值,我们会找到 UniqueID = "A" 为 1 的观察值的 Step 的最小值。对于 UniqueID 等于 "A",实际上有 1 个 1 的观察值,但我们想要的是最旧的观察值,即这就是为什么在输出数据框中选择观察 3。

标签: r dplyr subsequence


【解决方案1】:

相当低效,但工作。

首先定义一个函数:

myseq <- function(df){
  if(which.min(df$Step) == nrow(df)){
    return(list(df[nrow(df),]))
  }
  store <- vector(mode = "list", length = nrow(df))
  i=1
  while(any(!is.na(df$Step))){
    store[[i]] <-  df[which.min(df$Step),]
    df <- df[which.min(df$Step) : nrow(df), ]
    df$Step[df$Step == min(df$Step)] <- NA
    i = i+1
  }
  store
}

然后使用dplyr将其包装在数据帧上:

library(dplyr)
dta %>% group_by(UniqueID) %>%
        do(do.call(rbind, myseq(.)))
Source: local data frame [6 x 3]
Groups: UniqueID

  UniqueID       Date Step
1        A 2015-07-09    1
2        A 2015-07-20    2
3        A 2015-07-24    3
4        B 2015-06-22    1
5        B 2015-07-13    2
6        B 2015-07-27    4

【讨论】:

  • 嗨,谢谢。它确实适用于测试数据框。但是对于真实的数据集,它会崩溃。我已经为崩溃的真实数据集的 18 行样本提供了 dput,请参阅我对 OP 的编辑,为导致此解决方案崩溃的数据帧提供 dput。
  • 谢谢。这样可行。我已经尝试了 5000 行,但它崩溃了。你会期望这种情况发生吗?
  • 您好,我已将错误范围缩小到一个导致其崩溃的 UniqueID。我已将 dput 作为 OP 中的另一个编辑发布。我不明白它为什么会崩溃。
  • 我做了一些测试,问题似乎只有在第一个和最后一个步骤编号相同时才会出现,并且它们之间还有一些其他步骤编号。所以即使是 1、2、1 的序列也会崩溃。
  • 我可以通过将na.rm = TRUE 添加到此行来修复它:df$Step[df$Step == min(df$Step, na.rm=TRUE)] &lt;- NA1
猜你喜欢
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2016-02-05
相关资源
最近更新 更多