【问题标题】:Calculate if the change is greater than .25计算变化是否大于 0.25
【发布时间】:2021-08-25 19:41:05
【问题描述】:

考虑这个data.table

library(data.table)
dt1 <- data.table(id = c("01","01","01","01","01", "02","02","02",",02","02"),
                 change_total = c(.00,.90,-.10,.8,.3,.00,.90,-.10,.8,.3))

如何计算每个 ID 的行之间的变化是否大于 change_total 的 25% (change_greater_than_25_percent),然后如果这些“是”大于每个 ID 的行的 25%。 看起来像这样

dt2 <- data.table(id = c("01","01","01","01", "01","02","02","02","02","02"),
                 change_total = c(.00,.90,-.10,.8,.3,.00,.90,-.10,.8,.3),
                 change_greater_than_25_percent = c("no","yes","no","no","no","no","yes","no","no","no"),
                 change_greater_than_25_percent_greaterthan_25_percent_ofthe_time_by_id = c("no","yes","yes","yes","no","no","yes","yes","yes","no"))

【问题讨论】:

  • 那些预期的输出是否正确?我尝试了“change_greater_than_25_percent”,但根据您的输入给出了不同的输出

标签: r data.table


【解决方案1】:

我能够重现列 change_greater_than_25_percent 的预期结果:

library(data.table)
library(magrittr) # piping used to improve readability
dt1[, change_greater_than_25_percent := 
      (change_total / shift(change_total, fill = Inf) - 1. > 0.25) %>%  
      fifelse("yes", "no"), by = id][]
    id change_total change_greater_than_25_percent
 1: 01          0.0                             no
 2: 01          0.9                            yes
 3: 01         -0.1                             no
 4: 01          0.8                             no
 5: 01          0.3                             no
 6: 02          0.0                             no
 7: 02          0.9                            yes
 8: 02         -0.1                             no
 9: 02          0.8                             no
10: 02          0.3                             no

很遗憾,我不明白列change_greater_than_25_percent_greaterthan_25_percent_ofthe_time_by_id的确切定义

然后如果这些“是”按每个 id 的行数大于 25%

编辑 1

如果我理解正确Pan Dora's comment,第二列表示change_greater_than_25_percent(取为0,"no""yes"的值为1)的累积平均值大于0.25 .

如果将"no""yes"分别替换为逻辑值FALSETRUE,这将更容易计算,因为根据help("TRUE")

在需要数值的上下文中,逻辑向量被强制转换为整数向量,TRUE 被映射到 1LFALSE0LNANA_integer_

library(data.table)
dt1[, change_greater_than_25_percent := 
      change_total / shift(change_total, fill = Inf) - 1. > 0.25, by = id][
        , change_greater_than_25_percent_greaterthan_25_percent_ofthe_time_by_id := 
          cumsum(change_greater_than_25_percent) / (1:.N) >= 0.25, by = id][]
    id change_total change_greater_than_25_percent change_greater_than_25_percent_greaterthan_25_percent_ofthe_time_by_id
 1: 01          0.0                          FALSE                                                                  FALSE
 2: 01          0.9                           TRUE                                                                   TRUE
 3: 01         -0.1                          FALSE                                                                   TRUE
 4: 01          0.8                          FALSE                                                                   TRUE
 5: 01          0.3                          FALSE                                                                  FALSE
 6: 02          0.0                          FALSE                                                                  FALSE
 7: 02          0.9                           TRUE                                                                   TRUE
 8: 02         -0.1                          FALSE                                                                   TRUE
 9: 02          0.8                          FALSE                                                                   TRUE
10: 02          0.3                          FALSE                                                                  FALSE

注意事项

  1. 为了重现预期结果大于或等于 25% (&gt;= 0.25) 必须使用而不是大于 25% (&gt; 0.25 )。我没有修改已经很长的列名。
  2. 使用逻辑值代替字符简化了计算,因此我们不需要magrittr管道
  3. 使用了data.table 链接
  4. 为了计算累积平均值dplyr::cummean()自适应frollmean() 可以交替使用。

编辑 2

以上代码要求dt1 属于data.table 类。为确保,请致电

setDT(dt1)

事先。

【讨论】:

  • 该列 change_greater_than_25_percent_greaterthan_25_percent_ofthe_time_by_id 表示,第 1 行 change_greater_than_25_percent 为否,然后将其添加到第 2 行 change_greater_than_25_percent 如果大于 25% “是”或低于“否” 在这种情况下,第 1 行是否第二行是肯定的,所以平均为 50%,这导致 change_greater_than_25_percent_greaterthan_25_percent_ofthe_time_by_id 列是肯定的。然后添加第 3 行,它是“否”,现在平均值是 33%,所以这将是“是”,依此类推
  • 列“change_greater_than_25_percent_greaterthan_25_percent_ofthe_time_by_id”的意思是,第 1 行 change_greater_than_25_percent 是“否”,然后将其添加到第二行 change_greater_than_25_percent 如果大于 25%“是”或低于“否”在这种情况下,第 1 行是“否”,第 2 行是“是”,因此 avg 为 50%,这导致“change_greater_than_25_percent_greaterthan_25_percent_ofthe_time_by_id”列为“是”。然后添加第 3 行,这是“否”,现在平均值是“是”的 33%,所以这将是“是”,依此类推
  • 这是我运行代码时的错误代码 as.vector(x,list) 中的错误:无法将“闭包”类型强制转换为“列表”类型的向量
  • @PanDora 感谢您的额外解释!关于错误,请参阅我的第二次编辑。如果错误仍然存​​在,我们可能需要进一步检查输入数据。
猜你喜欢
  • 2020-07-13
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多