从具有每分钟最大值的数据帧到每个键的值

时间:2018-01-03 13:39:35

标签: r max lookup min

我有一个数据框,其中每个存储桶定义了值。 (见下面的df1) 现在我有另一个数据框,其中包含这些存储区中的值,我想从这个数据帧中查找一个值(参见下面的df2)

现在我想得到下面的结果df3。

df1 <- data.frame(MIN = c(1,4,8), MAX = c(3, 6, 10), VALUE = c(3, 56, 8))
df2 <- data.frame(KEY = c(2,5,9))
df3 <- data.frame(KEY = c(2,5,9), VALUE = c(3, 56, 8))

> df1
  MIN MAX VALUE
1   1   3     3
2   4   6    56
3   8  10     8
> df2
  KEY
1   2
2   5
3   9
> df3
  KEY VALUE
1   2     3
2   5    56
3   9     8

编辑: 扩展了这个例子。

> df1 <- data.frame(MIN = c(1,4,8, 14), MAX = c(3, 6, 10, 18), VALUE = c(3, 56, 3, 5))
> df2 <- data.frame(KEY = c(2,5,9,18,3))
> df3 <- data.frame(KEY = c(2,5,9,18,3), VALUE = c(3, 56, 3, 5, 3))
> df1
  MIN MAX VALUE
1   1   3     3
2   4   6    56
3   8  10     3
4  14  18     5
> df2
  KEY
1   2
2   5
3   9
4  18
5   3
> df3
  KEY VALUE
1   2     3
2   5    56
3   9     3
4  18     5
5   3     3

2 个答案:

答案 0 :(得分:1)

此解决方案假定KEYMINMAX是整数,因此我们可以创建一系列密钥然后加入。

df1 <- data.frame(MIN = c(1,4,8, 14), MAX = c(3, 6, 10, 18), VALUE = c(3, 56, 3, 5))
df2 <- data.frame(KEY = c(2,5,9,18,3))

library(dplyr)
library(purrr)
library(tidyr)

df1 %>%
  group_by(VALUE, id=row_number()) %>%             # for each value and row id
  nest() %>%                                       # nest rest of columns
  mutate(KEY = map(data, ~seq(.$MIN, .$MAX))) %>%  # create a sequence of keys
  unnest(KEY) %>%                                  # unnest those keys
  right_join(df2, by="KEY") %>%                    # join the other dataset
  select(KEY, VALUE) 

# # A tibble: 5 x 2
#     KEY VALUE
#   <dbl> <dbl>
# 1  2.00  3.00
# 2  5.00 56.0 
# 3  9.00  3.00
# 4 18.0   5.00
# 5  3.00  3.00

或者,只按行号分组并在VALUE中添加map

df1 %>%
  group_by(id=row_number()) %>% 
  nest() %>%                 
  mutate(K = map(data, ~data.frame(VALUE = .$VALUE, 
                                   KEY = seq(.$MIN, .$MAX)))) %>%
  unnest(K) %>%
  right_join(df2, by="KEY") %>% 
  select(KEY, VALUE)

答案 1 :(得分:0)

来自@AntioniosK的非常好且经过深思熟虑的解决方案。

这是一个基本R解决方案,作为一般查找函数实现,作为参数给出关键数据帧和定义为问题中列出的存储桶数据帧。在这个例子中,查找值不必是唯一的或连续的,考虑到@Michael的注释,即值可能出现在多行中(尽管通常这样的查找会使用唯一的范围)。

var mortgages_counter = $('#mortgages_counter').val().split('|');

第一次合并使用密钥中所有行的笛卡尔连接到存储桶列表中的所有行。如果实表中的行数很大,这样的连接可能效率低,因为将键中的x行连接到存储桶中的y行将是xy行;我怀疑在这种情况下这将是一个问题,除非x或y遇到数千行。

完成第二次合并以恢复匹配桶列表中的行的任何键值。

使用@ AntioniosK帖子中列出的示例数据:

lookup = function(keydf, bucketdf){
  keydf$rowid = 1:nrow(keydf)
  T = merge(bucketdf, keydf)
  T = T[T$KEY >= T$MIN & T$KEY <= T$MAX,]
  T = merge(T, keydf, all.y = TRUE)
  T[order(T$rowid), c("rowid", "KEY", "VALUE")]
}

使用测试边缘情况的密钥和存储桶示例(其中密钥=最小值或最大值),其中密钥值不在存储桶列表中(df2A中的值为50),以及存在非唯一的情况范围(下面df4第6行):

> lookup(df2, df1)
  rowid KEY VALUE
2     1   2     3
4     2   5    56
5     3   9     3
1     4  18     5
3     5   3     3

如上所示,在这种情况下,查找返回与键值22匹配的非唯一范围的两个值,以及键中值但不在桶列表中的值的NA。