比较数据框中的一列与另一数据框中的两列

时间:2019-11-05 22:25:23

标签: r dataframe

我有两个数据帧,我需要知道第一个数据帧的值是否在第二个数据帧的两个值(最小和最大值)之间。

在处理其他两个数据帧之前,我做了类似的事情,我使用了嵌套的loopbetween {dplyr}。但是,另一个数据集只有三个变量,我可以将其与8条if语句一起使用。这就是我遇到的问题,dataframe1具有62个变量和477个观测值,dataframe2具有124个变量和50个观测值(最小值和最大值)。下面有一个两个数据框的示例以及我要寻找的结果。

因此,我正在寻找一种无需编写约一千个if else语句的解决方案。我希望有人能提供帮助,或者甚至有可能。

关于数据外观的示例,我仍然可以更改数据框,但这正是我所要面对的。

Df1
   id type data1 data2 data3
1   1   ab     0     0     0
2   2   cd     0     0     0
3   3   dd     0    10     5
4   4   ed     0     0     0
5   5   kd     0     0    15
6   6   xd     0     5     0
7   7   ab     0     0     0
8   8   cd     0     0     0
9   9   dd     0    10    10
10 10   ed     0     0     0
11 11   kd     0     0    12
12 12   xd     0    12     0
13 13   ab     0     0     0
14 14   cd     0     0     0
15 15   dd     0     5    15
16 16   ed     0     0     0
17 17   kd     0     0    15
18 18   xd     0     7     0
19 19   ab     0     0     0
20 20   cd     0     0     0
21 21   dd     0    18    10
22 22   ed     0     0     0
23 23   kd     0     0     5

我通常将“类型”彼此匹配,然后如果数据在上下边界之间,则匹配。

Df2
  type data1 data1max data2 data2max data3 data3max
1   ab    NA       NA    NA       NA    NA       NA
2   dd    NA       NA     5       20    10      100
3   xd    NA       NA     1       30    NA       NA
4   ed    NA       NA    NA       NA    NA       NA
5   cd    NA       NA    NA       NA    NA       NA
6   kd    NA       NA    NA       NA     5       20

并在观察到的数据与合格数据匹配时进行计数。

Df3
   id type qualifyingfields
1   1   ab                0
2   2   cd                0
3   3   dd                1
4   4   ed                0
5   5   kd                1
6   6   xd                1
7   7   ab                0
8   8   cd                0
9   9   dd                2
10 10   ed                0
11 11   kd                1
12 12   xd                1
13 13   ab                0
14 14   cd                0
15 15   dd                2
16 16   ed                0
17 17   kd                1
18 18   xd                1
19 19   ab                0
20 20   cd                0
21 21   dd                1
22 22   ed                0
23 23   kd                1

2 个答案:

答案 0 :(得分:0)

exportAs

数据:

library(dplyr)
library(tidyr)

df1 %>% 
  right_join(., df2, by = "type", suffix = c("val", "min")) %>% 
  group_by(type, id) %>% 
  pivot_longer(-c(id, type), names_to = "data", values_to = "value") %>% 
  separate(col = data, into = c("data", "var"), sep = "(?<=\\d)") %>% 
  pivot_wider(names_from = var, values_from = value) %>% 
  group_by(id, type, data) %>% 
  mutate(qualifyingfields = sum(between(val, min, max), na.rm = T)) %>% 
  group_by(id, type) %>% 
  summarise(qualifyingfields = sum(qualifyingfields))

#> # A tibble: 23 x 3
#> # Groups:   type, id [23]
#>       id type  qualifyingfields
#>    <int> <chr>            <int>
#>  1     1 ab                   0
#>  2     2 cd                   0
#>  3     3 dd                   1
#>  4     4 ed                   0
#>  5     5 kd                   1
#>  6     6 xd                   1
#>  7     7 ab                   0
#>  8     8 cd                   0
#>  9     9 dd                   2
#> 10    10 ed                   0
#> # ... with 13 more rows

答案 1 :(得分:0)

这是一种适用于数据的更通用的解决方案,而不管data[n]列有多少

library('dplyr')
library('tidyr')

# Make dataframes tidy
Df1_tidy <- Df1 %>%   
    gather(key='data_name', value='value', -(id:type))

Df2_tidy <- Df2 %>%
    gather(key='data_name', value='value', -type) %>%
    mutate(limit=ifelse(grepl('max', data_name), 'Max', 'Min'),
           data_name=gsub('max', '', data_name)) %>% 
    spread(limit, value) 

# Count qualifying fields
Df3 <- full_join(Df1_tidy, Df2_tidy) %>%
    group_by(id, type) %>%
    summarise(qualifyingfields = sum(value >= Min & value <= Max, na.rm=T)) %>%
    ungroup()

Df3
# # A tibble: 23 x 3
#       id type  qualifyingfields
#    <int> <chr>            <int>
#  1     1 ab                   0
#  2     2 cd                   0
#  3     3 dd                   1
#  4     4 ed                   0
#  5     5 kd                   1
#  6     6 xd                   1
#  7     7 ab                   0
#  8     8 cd                   0
#  9     9 dd                   2
# 10    10 ed                   0
# # ... with 13 more rows

获取数据(从@ M--响应复制):

df1 <- read.table(text="   id type data1 data2 data3
1   1   ab     0     0     0
2   2   cd     0     0     0
3   3   dd     0    10     5
4   4   ed     0     0     0
5   5   kd     0     0    15
6   6   xd     0     5     0
7   7   ab     0     0     0
8   8   cd     0     0     0
9   9   dd     0    10    10
10 10   ed     0     0     0
11 11   kd     0     0    12
12 12   xd     0    12     0
13 13   ab     0     0     0
14 14   cd     0     0     0
15 15   dd     0     5    15
16 16   ed     0     0     0
17 17   kd     0     0    15
18 18   xd     0     7     0
19 19   ab     0     0     0
20 20   cd     0     0     0
21 21   dd     0    18    10
22 22   ed     0     0     0
23 23   kd     0     0     5", 
header=T, stringsAsFactors=F)

df2 <- read.table(text="  type data1 data1max data2 data2max data3 data3max
1   ab    NA       NA    NA       NA    NA       NA
2   dd    NA       NA     5       20    10      100
3   xd    NA       NA     1       30    NA       NA
4   ed    NA       NA    NA       NA    NA       NA
5   cd    NA       NA    NA       NA    NA       NA
6   kd    NA       NA    NA       NA     5       20", 
header=T, stringsAsFactors=F, na.strings = "NA")