从每个唯一对中获取信息

时间:2019-01-21 16:42:44

标签: r unique extract

我有每个站点的坐标以及每个站点采样的年份(以下为伪数据框)。

dfA<-matrix(nrow=20,ncol=3)
dfA<-as.data.frame(dfA)
colnames(dfA)<-c("LAT","LONG","YEAR")
#fill LAT
dfA[,1]<-rep(1:5,4)
#fill LONG
dfA[,2]<-c(rep(11:15,3),16:20)
#fill YEAR
dfA[,3]<-2001:2020

> dfA
    LAT LONG YEAR
 1    1   11 2001
 2    2   12 2002
 3    3   13 2003
 4    4   14 2004
 5    5   15 2005
 6    1   11 2006
 7    2   12 2007
 8    3   13 2008
 9    4   14 2009
 10   5   15 2010
 11   1   11 2011
 12   2   12 2012
 13   3   13 2013
 14   4   14 2014
 15   5   15 2015
 16   1   16 2016
 17   2   17 2017
 18   3   18 2018
 19   4   19 2019
 20   5   20 2020

我想退出每个唯一位置被采样的年份。因此,我首先使用以下代码提取了每个唯一的位置及其采样时间

dfB <- dfA %>% 
group_by(LAT, LONG) %>%
summarise(Freq = n())
dfB<-as.data.frame(dfB) 

   LAT LONG Freq
1    1   11    3
2    1   16    1
3    2   12    3
4    2   17    1
5    3   13    3
6    3   18    1
7    4   14    3
8    4   19    1
9    5   15    3
10   5   20    1

我现在正在尝试获取每个唯一位置的年份。即我最终想要这个:

   LAT LONG Freq .  Year
1    1   11    3 .  2001,2006,2011
2    1   16    1 .  2016
3    2   12    3 .  2002,2007,2012
4    2   17    1
5    3   13    3
6    3   18    1
7    4   14    3
8    4   19    1
9    5   15    3
10   5   20    1

这是我尝试过的:

1)在dfA中找到与dfB相对应的行:

dfB$obs_Year<-NA
idx <- match(paste(dfA$LAT,dfA$LONG), paste(dfB$LAT,dfB$LONG))

> idx
[1]  1  3  5  7  9  1  3  5  7  9  1  3  5  7  9  2  4  6  8 10

因此idx [1]表示dfA [1]与dfB [1]相匹配。 dfA [6],df [11]全部与dfB [1]匹配。

我已经尝试过提取信息:

for (row in 1:20){
  year<-as.character(dfA$YEAR[row])
  tmp<-dfB$obs_Year[idx[row]]
  if(isTRUE(is.na(dfB$obs_Year[idx[row]]))){
    dfB$obs_Year[idx[row]]<-year
  }
  if(isFALSE(is.na(dfB$obs_Year[idx[row]]))){
    dfB$obs_Year[idx[row]]<-as.list(append(tmp,year))
  }
}

我不断收到此错误代码:

number of items to replace is not a multiple of replacement length

有人知道如何从匹配的dfA对dfB中提取年份吗?我不知道这是否是最有效的代码,但是据我所知……。谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使用dplyr链来做到这一点,该链首先构建您的日期列,然后仅过滤到唯一的观察值。

逻辑是通过按位置对数据进行分组来构建日期变量,然后将给定位置的所有日期粘贴到单个字符串变量(我们称为year_string)中。然后,我们还计算频率,但这不是严格必要的。

数据中唯一随时间变化的列是YEAR,这意味着如果我们排除该列,您将看到位置重复的值。因此,我们排除了YEAR列,然后要求R向我们返回data.frame的unique()值。它会在发生多个位置的每个位置选择一个观测值,但是由于它们是相同的,所以没有关系。

以下代码:

library(dplyr)

dfA<-matrix(nrow=20,ncol=3)
dfA<-as.data.frame(dfA)
colnames(dfA)<-c("LAT","LONG","YEAR")
#fill LAT
dfA[,1]<-rep(1:5,4)
#fill LONG
dfA[,2]<-c(rep(11:15,3),16:20)
#fill YEAR
dfA[,3]<-2001:2020

# We assign the output to dfB
dfB <- dfA %>% group_by(LAT, LONG) %>% # We group by locations
  mutate( # The mutate verb is for building new variables.
    year_string = paste(YEAR, collapse = ","), # the function paste()
                          # collapses the vector YEAR into a string
                          # the argument collapse = "," says to 
                          # separate each element of the string with a comma
         Freq = n()) %>% # I compute the frequency as you did
  select(LAT, LONG, Freq, year_string) %>% 
             # Now I select only the columns that index
             # location, frequency and the combined years
  unique() # Now I filter for only unique observations. Since I have not picked
           # YEAR in the select function only unique locations are retained

dfB
#> # A tibble: 10 x 4
#> # Groups:   LAT, LONG [10]
#>      LAT  LONG  Freq year_string   
#>    <int> <int> <int> <chr>         
#>  1     1    11     3 2001,2006,2011
#>  2     2    12     3 2002,2007,2012
#>  3     3    13     3 2003,2008,2013
#>  4     4    14     3 2004,2009,2014
#>  5     5    15     3 2005,2010,2015
#>  6     1    16     1 2016          
#>  7     2    17     1 2017          
#>  8     3    18     1 2018          
#>  9     4    19     1 2019          
#> 10     5    20     1 2020

reprex package(v0.2.1)于2019-01-21创建