仅最近整数上的R-模糊连接

仅最近整数上的R-模糊连接,r,dplyr,fuzzyjoin,R,Dplyr,Fuzzyjoin,假设我从这个数据集开始,在这个愚蠢的布局中: 从这里看来,使用索引(行号)似乎是最好的方法,即将detailsDF中的每一行与namedf中索引最接近的条目进行匹配,而无需进行检查。我使用了fuzzyjoin包,并用 fuzzy_left_join(detailsDF, namesDF, by = "Index", match_fun = list(`>`)) 这类方法可行,但它也会将detailsDF中的每一行与namedf中的每一行连接起来,索引号较小: 我提出了一个解决方案,使

假设我从这个数据集开始,在这个愚蠢的布局中:

从这里看来,使用索引(行号)似乎是最好的方法,即将
detailsDF
中的每一行与
namedf
中索引最接近的条目进行匹配,而无需进行检查。我使用了
fuzzyjoin
包,并用

fuzzy_left_join(detailsDF, namesDF, by = "Index", match_fun = list(`>`))
这类方法可行,但它也会将
detailsDF
中的每一行与
namedf
中的每一行连接起来,索引号较小:

我提出了一个解决方案,使用到下一个索引的距离,并以这种方式过滤掉多余的行,但我希望避免这样做;实际的源文件将超过200k行,临时生成的带有额外行的数据帧将太大,无法放入内存中。这里有什么我能做的吗?谢谢

您可以使用

x = which(originalDF$Field == "Name")
originalDF$Name = rep(originalDF$Value[x], times = diff(c(x, NROW(originalDF)+1)))
NewDF = originalDF[originalDF$Field != 'Name', c(4,2,3)]
#    Name  Field Value
# 2  Sara Weight   115
# 3  Sara    Age    17
# 5   Bob Weight   158
# 6   Bob    Age    22
# 7   Bob Height    72
# 9   Irv Weight   210
# 10  Irv    Age    42
# 11  Irv Height    68
# 13 Fred    Age   155
# 14 Fred Height    65

我建议以不同的方式处理它,在每个点跟踪最新的“Name”值fill()对此很有用

library(dplyr)
library(tidyr)

originalDF %>%
  mutate(Name = ifelse(Field == "Name", as.character(Value), NA)) %>%
  fill(Name) %>%
  filter(Field != "Name")
输出:

   Index  Field Value Name
1      2 Weight   115 Sara
2      3    Age    17 Sara
3      5 Weight   158  Bob
4      6    Age    22  Bob
5      7 Height    72  Bob
6      9 Weight   210  Irv
7     10    Age    42  Irv
8     11 Height    68  Irv
9     13    Age   155 Fred
10    14 Height    65 Fred
# A tibble: 10 x 6
   Index.x Field.x Value.x Index.y Field.y Value.y
     <int> <fct>   <fct>     <int> <fct>   <fct>  
 1       2 Weight  115           1 Name    Sara   
 2       3 Age     17            1 Name    Sara   
 3       5 Weight  158           4 Name    Bob    
 4       6 Age     22            4 Name    Bob    
 5       7 Height  72            4 Name    Bob    
 6       9 Weight  210           8 Name    Irv    
 7      10 Age     42            8 Name    Irv    
 8      11 Height  68            8 Name    Irv    
 9      13 Age     155          12 Name    Fred   
10      14 Height  65           12 Name    Fred   

但是,如果您确实想使用fuzzyjoin方法,您可以通过在结果上使用
groupby()
slice()
来实现这一点,您可以为
Index.x
的每个值获取最后一行

fuzzy_left_join(detailsDF, namesDF, by = "Index", match_fun = list(`>`)) %>%
  group_by(Index.x) %>%
  slice(n()) %>%
  ungroup()
输出:

   Index  Field Value Name
1      2 Weight   115 Sara
2      3    Age    17 Sara
3      5 Weight   158  Bob
4      6    Age    22  Bob
5      7 Height    72  Bob
6      9 Weight   210  Irv
7     10    Age    42  Irv
8     11 Height    68  Irv
9     13    Age   155 Fred
10    14 Height    65 Fred
# A tibble: 10 x 6
   Index.x Field.x Value.x Index.y Field.y Value.y
     <int> <fct>   <fct>     <int> <fct>   <fct>  
 1       2 Weight  115           1 Name    Sara   
 2       3 Age     17            1 Name    Sara   
 3       5 Weight  158           4 Name    Bob    
 4       6 Age     22            4 Name    Bob    
 5       7 Height  72            4 Name    Bob    
 6       9 Weight  210           8 Name    Irv    
 7      10 Age     42            8 Name    Irv    
 8      11 Height  68            8 Name    Irv    
 9      13 Age     155          12 Name    Fred   
10      14 Height  65           12 Name    Fred   
#一个tible:10 x 6
Index.x Field.x Value.x Index.y Field.y Value.y
1 2重量115 1姓名Sara
2 3 17岁1叫莎拉
3 5重量158 4姓名鲍勃
4 6岁22 4叫鲍勃
5 7高度72 4姓名Bob
6 9重量210 8名称Irv
7 10岁42 8姓名Irv
8 11高度68 8名称Irv
9 13岁155 12叫弗雷德
10 14身高65 12姓名Fred

您可以通过
cumsum(Field==“Name”)
进行分组。用dplyr

library(dplyr) 
originalDF %>% 
  group_by(Name = Value[Field == "Name"][cumsum(Field == "Name")]) %>%
  slice(-1) %>% select(c("Name", "Field", "Value"))

# A tibble: 10 x 3
# Groups:   Name [4]
   Name  Field  Value
   <fct> <fct>  <fct>
 1 Bob   Weight 158  
 2 Bob   Age    22   
 3 Bob   Height 72   
 4 Fred  Age    155  
 5 Fred  Height 65   
 6 Irv   Weight 210  
 7 Irv   Age    42   
 8 Irv   Height 68   
 9 Sara  Weight 115  
10 Sara  Age    17   

谢谢我知道我忽略了一些更简单的事情。我还几乎记住了哈德利的《数据科学R》一书的部分内容。。。
library(data.table)
data.table(originalDF)[, 
  .SD[-1], 
by=.(Name = Value[Field == "Name"][cumsum(Field == "Name")]), .SDcols=c("Field", "Value")]