R:如何忽略pmin上的某些值

时间:2016-04-29 07:32:46

标签: r data.table

我有两个data.table s

DT <- data.table(name = c("a","b","c","d"),
                 "850Hz" = c(0,1,1,0),
                 "1800Hz" = c(2,0,2,0),
                 "2100Hz" = c(0,3,0,3),
                 "2600Hz" = c(4,0,0,4))
Info <- data.table(Freq = c("850Hz", "1800Hz", "2100Hz", "2600Hz"), Rng = c(3000, 2000, 1800, 1000))

我想在DT中创建一个名为“Range”的新列,对每一行进行如下操作: 如果行在“850Hz”列中包含不同于0的数字,则应考虑值3000(根据data.table信息中“850Hz”和3000之间建立的关联)。然后,如果“1800Hz”列中存在非零数字,则应考虑值2000,以此类推其他2列。最后,它应该计算该行的所有考虑值的最大值,并将其写入新列“Range”中。 等等其他行。

有人建议我使用这段代码:

Info[, {
  DT[, Range := pmax(Range, (get(Freq) != 0) * Rng, na.rm = TRUE)]
  NULL
}, by = Freq]

我不明白它是如何工作的,但它确实起了作用。我的问题是,为什么我想要为每行而不是最大值的MINIMUM考虑值?如果我使用pmin,对于此特定示例,“范围”列中的所有值都将为0,因为 会考虑列中值为0的情况(“850Hz”等等,我想它将零乘以相应的值。我需要告诉它忽略这4列中的零。怎么样?

一个可能的答案是将这些列中的所有零转换为N/A,然后使用na.rm = TRUE。但我无法弄清楚如何进行选择性替换。要考虑的列数(850Hz,1800Hz,2100Hz,本例中为2600Hz)可能小于4 。这是因为根据数据,这4列中的一个或多个可能会丢失。我需要考虑DT中名称存在于向量Info [,Freq]中的所有列。然后,仅更改N/A的那些列中的所有0。我每次都在尝试和失败。

1 个答案:

答案 0 :(得分:1)

我会以长格式保存主要数据:

DT_long = melt(DT, id="name", variable.name="Freq")[value != 0]

并且可能会添加Rng

中的Info
DT_long[Info, Rng := i.Rng, on="Freq"]
# or
Info_cols = setdiff(names(Info), "Freq")
DT_long[Info, (Info_cols) := mget(Info_cols), on="Freq"]

要以宽屏格式显示摘要,您可以使用dcast

res = cbind( 
  dcast(DT_long, name ~ Freq), 
  dcast(DT_long, name ~ ., value.var = "Rng", fun = list(min, max))[, name := NULL]
)

   name 850Hz 1800Hz 2100Hz 2600Hz Rng_min_. Rng_max_.
1:    1    NA      2     NA      4      1000      2000
2:    2     1     NA      3     NA      1800      3000
3:    3     1      2     NA     NA      2000      3000
4:    4    NA     NA      3      4      1000      1800

不幸的是,我不知道在最后两列中摆脱尾随_.的快速方法;也许这个功能将在以后添加。有各种解决方法,如

res = cbind( 
  dcast(DT_long, name ~ Freq), 
  DT_long[, c(Rng = list(min = min(Rng), max = max(Rng))), keyby=name][, name := NULL]
)