我在R中有两个数据框,我已经完成了其他一些我已经完成的工作。
一个是宽表,包含几个数字。我们称之为x1和x2。这些变量可以采用-999到999之间的值。
另一个数据框是一个长表,包含var,min,max和group的列。这些本质上是一组if-than规则。这是一个例子:
# look up table example
var <- c('x1', 'x1', 'x1', 'x2', 'x2')
min <- c(-999, 5, 70, -999, 20)
max <- c(5, 70, 999, 20, 999)
group <- c(1,2,3,1,2)
lkup<- data.frame(var, min, max, group)
表中的数据可以作为一组if-than语句读取。例如,此表c的第一行(&#39; x1&#39;, - 1999,5,1)表示在-999和5之间的x1中的任何值都应映射到新变量中的1我们&#39 ;打电话给y1。表中的所有行都可以以类似的方式解释。
y1应该从x1获取所有映射。所以它最终应该有与x1规则一样多的唯一值。
我希望能够根据df中的数据和查找表中的规则创建一个新的数据框。
所以,例如,如果我有上面的查找表和数据:
# data
x1 <- c(1, 2, 50, 70 , 100)
x2 <- c(2, 3, 4, 50, 60)
df <- data.frame(x1, x2)
我应该得到一张如下所示的表:
# Desired result
y1 <- c(1, 1, 2, 2, 3)
y2 <- c(1, 1, 1, 2, 2)
result <- data.frame(y1, y2)
我认为这是解决我遇到的问题的一个很好的解决方案,但实际上完成这项工作证明是具有挑战性的。任何人都可以给我的指导将非常感激。
答案 0 :(得分:1)
使用tidyr
和library(dplyr); library(tidyr);
result <- merge(lkup, gather(df, var, value), by = "var") %>%
filter(value > min & value <= max) %>%
select(var, group) %>%
group_by(var) %>% mutate(id = seq_len(n())) %>%
spread(var, group) %>% select(-id)
> result
Source: local data frame [5 x 2]
x1 x2
(dbl) (dbl)
1 1 1
2 1 1
3 2 1
4 2 2
5 3 2
包的解决方案:
df
id x1 x2
1 1 1 2
2 2 2 3
3 3 50 4
4 4 70 50
5 5 100 60
merge(lkup, gather(df, var, value, -id), by = "var") %>%
filter(value > min & value <= max) %>%
select(id, var, group) %>% spread(var, group)
id x1 x2
1 1 1 1
2 2 1 1
3 3 2 1
4 4 2 2
5 5 3 2
要考虑原始数据集的顺序,您可以在数据中添加 id 变量,使每条记录都具有唯一性和可追溯性:
{{1}}