在执行查找时遇到错误,以及执行相同操作的更好方法

时间:2013-08-31 09:27:56

标签: r

我正在尝试执行查找以检测观察数据框中的异常值。查找数据帧df_ref相当小(约50行),观察数据帧约为200,000行。以下代码解释了示例数据和我的方法:

df_ref = data.frame(id = c(2, 7, 12), ref = c(15, 27, 32))
df_obs = data.frame(obs = rep(11, 4), val = c(3, 4, 7, 13))

查找基于以下逻辑(数据以df_ref编码。

if val >= 2 and val < 7 then ref = 15 
if val >= 7 and val < 12 then ref = 27 
if val >= 12 then ref = 32 

我想在使用df_val中的val和df_ref的(id,ref)中基于上述逻辑确定的df_obs中添加列ref_val。

以下R函数正确执行查找

get_ref = function(x, df_ref) {
    df_ref[df_ref$id == max(df_ref$id[x >= df_ref$id]), "val"]
}

当我在df_obs上使用此功能时,例如

mutate(df_obs, ref=get_ref(val, df_ref))

I get the following error:

  obs val
1  11   3
2  11   4
3  11   7
4  11  13
Warning message:
In x >= df_ref$id :
  longer object length is not a multiple of shorter object length

最终输出应该看起来像

df_obs

  obs val  ref
1  11   3   15
2  11   4   15
3  11   7   27
4  11  13   32

我在这里做错了什么?什么是更好的R-ish方式来完成这个查找?请帮忙。

问候

ķ

2 个答案:

答案 0 :(得分:3)

您正在将df_obs$valdf_ref$id进行比较,并且R警告您它们长度不相等,它可能会做一些您不期望的事情,即它会回收较短的矢量。< / p>

我会使用data.tables进行滚动连接:

library(data.table)
dt_ref <- data.table(df_ref, key = "id")
dt_obs <- data.table(df_obs, key = "val")

dt_ref[dt_obs, roll = TRUE]

#    id ref obs
# 1:  3  15  11
# 2:  4  15  11
# 3:  7  27  11
# 4: 13  32  11

答案 1 :(得分:1)

cut可能会引起人们的兴趣(但是它的语法有时需要花些时间来熟悉它)。

cut(df_obs$val, 
    breaks = c(df_ref$id, Inf), 
    labels = df_ref$ref, 
    right = FALSE)
# [1] 15 15 27 32
# Levels: 15 27 32

输出为factor,如果您需要numeric,则必须执行as.numeric(as.character(...))