R:匹配数据框中的值

时间:2018-04-12 15:46:55

标签: r list dataframe match

我有以下数据框列表:

a<-data.frame(
  Data0=c("Y","Y","Y","Y","Y","Y","N","N","N","N","N","N"),
  Data1=c(16,18,19,20,21,50,16,18,19,20,21,50),
  Data2=c(2.2291,2.0743,1.9369,1.8148,1.7064,1.6102,2.2291,2.0743,1.9369,1.8148,1.7064,1.6102)
)
b<-data.frame(
  Data0=c(-2 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ,10 ,11) ,
  Data1=c(0.8891 ,0.8891,0.9051,1,0.8891,0.8891,0.7907,0.8891,0.9929,0.8891,0.8891,0.8891,0.8891)
)
dfl<-list(a,b)

我想为列表中的每个数据帧创建一个函数,该函数返回最后一列中的数字,用于前面列中的匹配变量。

对于 a ,如果我发送&#34; Y&#34; 16,我想要2.2291和 b ,如果我发送5我想要0.7907。 a 的问题在于,如果我发送一个小于16的数字,对于&#34; Y&#34;或&#34; N&#34;,我希望它返回值,就像它是16,而不操纵输入变量。我设法为 b 执行此操作,但对于 a ,我有一个&#34; split&#34;介于&#34; Y&#34;和&#34; N&#34;,我不知道如何解决这个问题。

到目前为止:

get_value<-function(vector){
  if (length(vector)==1) {
    from<-append(head(unlist(dfl[[2]][1],use.names=FALSE),-1),-9999,0)
    to  <-unlist(dfl[[2]][1],use.names=FALSE)

    match_from<-vector > from
    match_to<-vector <=to

    pos<-which(match_from==match_to)
    return(unlist(dfl[[2]][pos,2]))
  }
  else{
    print("not sure what to do for a")
  }
}
get_value(4)
get_value(-44)

解决方案需要考虑到有时候对于 a ,Data0和Data1列已经切换了位置。

修改:  输入/输出表:

INPUT       OUTPUT

c("Y",13) -->   2.2291

c("Y",50) -->   1.6102

c("N",20) -->   1.8148

c("N",50) -->   1.6102

c(-44))   -->     0.8891

2 个答案:

答案 0 :(得分:1)

好的,我终于找到了办法,但它并不那么优雅,所以请帮助。

get_value<-function(vector){
  if (length(vector)==1) {
    from<-append(head(unlist(dfl[[2]][1],use.names=FALSE),-1),-9999,0)
    to  <-unlist(dfl[[2]][1],use.names=FALSE)

    match_from<-vector > from
    match_to<-vector <=  to

    pos<-which(match_from==match_to)
    return(unlist(dfl[[2]][pos,2]))
  }
  else{

    pos_1<-which(unlist(dfl[[1]][1],use.names=FALSE)==vector[1])

    from<-append(head(as.numeric(unlist(dfl[[1]][2],use.names=FALSE))[pos_1],-1),-9999,0)
    to  <-as.numeric(unlist(dfl[[1]][2],use.names=FALSE))[pos_1]

    match_from<-as.numeric(vector[2]) > from
    match_to  <-as.numeric(vector[2]) <=to
    pos<-pos_1[match_from == match_to]
    return(unlist(dfl[[1]][pos,3]))
  }
}

答案 1 :(得分:1)

使用tidyverse函数的替代方法如下:

library(tidyverse)
library(magrittr)

get_value<-function(vector){
  if (length(vector)==1) 
  { df <- dfl[[2]]
    k <- df %>%
      arrange(Data0)%>%
      filter(Data0 >= vector) %>%
      select(Data1) %>%
      head(1)
  }
  else
  {df <- dfl[[1]]
  k <- df %>%
    arrange(Data0)%>%
    filter(Data0 == vector[1]) %>%
    filter(Data1 >= vector[2]) %>%
    select(Data2) %>%
    head(1)
  }
  return(k)
}

并测试一些输出:

> get_value(c(-44))
   Data1
1 0.8891
> get_value(c('N',16))
   Data2
1 2.2291
> get_value(c('Y',16))
   Data2
1 2.2291
> get_value(c('N',12))
   Data2
1 2.2291
> get_value(c('Y',11))
   Data2
1 2.2291
> get_value(c('Y',18))
   Data2
1 2.0743