【问题标题】:Create a column for days sampled e.g. 0,10,30 days,starting with 0 days for every study area?为采样天数创建一个列,例如0,10,30 天,从每个研究区域的 0 天开始?
【发布时间】:2021-06-12 10:51:46
【问题描述】:

我喜欢为物种数据创建一些采样努力曲线。在某个时间段内重新采样的具有多个采样地块的几个研究区域在哪里。我的数据集和这个类似:

    df1 <- data.frame(PlotID = c("A","A","A","A","A","B","B","B","B","B","C","C","C","C","C","D","D","D","D","D","E","E","E"),
                  species = c("x","x","x1","x","x1","x2","x1","x3","x4","x4","x5","x5","x","x3","x","x3","x3","x4","x5","x","x1","x2","x3"),
                  date = as.Date(c("27-04-1995",    "26-05-1995",   "02-08-1995",   "02-05-1995",   "28-09-1995",   "02-08-1994",   "31-05-1995",   "27-07-1995",   "06-12-1995",   "03-05-1996",   "27-04-1995",   "31-05-1995",   "29-06-1994",   "30-08-1995",   "26-05-1994",   "30-05-1995",   "30-06-1995",   "30-06-1995",   "30-06-1995",   "30-08-1995",   "31-08-1995",   "01-09-1995","02-09-1995"),'%d-%m-%Y'),
                  area= c("A","A","A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","B","B","C","C","C"))

我真的很想要一个输出,它可以为我提供额外的采样时间列,例如整个数据框为 0、10 天、30 天,但每个区域的时间应从 0 开始。我试过这个:

effort<-df1%>% arrange(PlotID, date,species) %>% group_by(area) %>%
  mutate(diffDate = difftime(date, lag(date,1))) %>% ungroup()

但不知何故我的代码产生了废话? 有没有大神赐教?

T 最后我想实现下面这个例子。每个研究领域的矩阵列表,其中物种为行,但不以采样图为列,而是时间(以天为单位,显示采样工作量的增加)。该示例显示了 iNEXT 包中的数据集。但我坚持计算采样日期之间每个区域的采样天数。现在我只想要这个额外的列显示每个区域的采样事件与发现的物种之间的天数。我希望现在它更清楚一点?

编辑:这是我真实数据集中的日期的样子:

output from dput(head(my.data))
date= structure(c(801878400, 798940800, 780710400, 769910400, 775785600, 798940800), class = c("POSIXct", "POSIXt"), tzone = "UTC")

【问题讨论】:

  • 您好,您希望“A”区域中的第一个样本为 0,第二个为该区域第一次采样后经过的天数,对吧?
  • 不太清楚你想要完成什么。您努力的 diffDate 应该是当前样本和先前样本(仅按区域分组?)或当前和第一个样本(按区域分组?)之间的差异,您是否可以编写具有所需结果的模拟数据框。
  • 您能否显示共享数据的预期输出?
  • 对不起,我刚刚更新了我的问题。 @Pedro Alencar 每个区域的所有地块都应在每次采样事件的同一天进行采样。所以是的,每个区域的第一个采样日期应该是 0,接下来的每个日期都应该显示自开始日期以来经过的天数。

标签: r date tidyr


【解决方案1】:

一个可能的tidyverse 解决方案是

library(dplyr)

df1 %>% arrange(area, date) %>% 
  group_by(area)  %>% 
  mutate(diff_date_from_start = date - min(date), 
         diff_date_from_prev = date - lag(date))
#> # A tibble: 23 x 6
#> # Groups:   area [3]
#>    PlotID species date       area  diff_date_from_start diff_date_from_prev
#>    <chr>  <chr>   <date>     <chr> <drtn>               <drtn>             
#>  1 B      x2      1994-08-02 A       0 days              NA days           
#>  2 A      x       1995-04-27 A     268 days             268 days           
#>  3 A      x       1995-05-02 A     273 days               5 days           
#>  4 A      x       1995-05-26 A     297 days              24 days           
#>  5 B      x1      1995-05-31 A     302 days               5 days           
#>  6 B      x3      1995-07-27 A     359 days              57 days           
#>  7 A      x1      1995-08-02 A     365 days               6 days           
#>  8 A      x1      1995-09-28 A     422 days              57 days           
#>  9 B      x4      1995-12-06 A     491 days              69 days           
#> 10 B      x4      1996-05-03 A     640 days             149 days           
#> # … with 13 more rows
  • 如果您还按其他变量(例如 speciesPlotID)分组,diff_date_from_prev 变量可能更有意义。
  • diff_date_from_prev 计算每个区域的当前样本与第一个样本之间的天数差异。

编辑回答评论:

您的 date 存储为 POSIX 而不是 Date 类。如果时区不相关,我发现使用Date 更容易,因此一种选择是转换为日期as.Date(),然后应用前面所述的操作。或者,您可以使用 @Rui Barradas 在 cmets 中建议的 difftime() 函数并相应地指定单位。

df1 <- data.frame(PlotID = c("A","A","A","A","A","B","B","B","B","B","C","C","C","C","C","D","D","D","D","D","E","E","E"),
                  species = c("x","x","x1","x","x1","x2","x1","x3","x4","x4","x5","x5","x","x3","x","x3","x3","x4","x5","x","x1","x2","x3"),
                  # date as posix not as date. they are different data classs.  
                  date = as.POSIXct(c("27-04-1995",    "26-05-1995",   "02-08-1995",   "02-05-1995",   "28-09-1995",   "02-08-1994",   "31-05-1995",   "27-07-1995",   "06-12-1995",   "03-05-1996",   "27-04-1995",   "31-05-1995",   "29-06-1994",   "30-08-1995",   "26-05-1994",   "30-05-1995",   "30-06-1995",   "30-06-1995",   "30-06-1995",   "30-08-1995",   "31-08-1995",   "01-09-1995","02-09-1995"),'%d-%m-%Y'),
                  area= c("A","A","A","A","A","A","A","A","A","A","B","B","B","B","B","B","B","B","B","B","C","C","C"))


library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
df1 %>% arrange(area, date) %>% 
  group_by(area)  %>% 
  mutate(
    date = as.Date(date),
    diff_date_from_start = date - min(date)
  )
#> # A tibble: 23 x 6
#> # Groups:   area [3]
#>    PlotID species date       area  diff_date_from_start diff_date_time
#>    <chr>  <chr>   <date>     <chr> <drtn>               <drtn>        
#>  1 A      x       2-05-19    A         0 days               0 days    
#>  2 A      x1      2-08-19    A        92 days              92 days    
#>  3 B      x2      2-08-19    A        92 days              92 days    
#>  4 B      x4      3-05-19    A       365 days             365 days    
#>  5 B      x4      6-12-19    A      1675 days            1675 days    
#>  6 A      x       26-05-19   A      8766 days            8766 days    
#>  7 A      x       27-04-19   A      9101 days            9101 days    
#>  8 B      x3      27-07-19   A      9192 days            9192 days    
#>  9 A      x1      28-09-19   A      9620 days            9620 days    
#> 10 B      x1      31-05-19   A     10592 days           10592 days    
#> # … with 13 more rows
# or as suggested by Rui Barradas. you can use difftime function and keep you date as a POSIX class
df1 %>% arrange(area, date) %>% 
  group_by(area)  %>% 
  mutate(
    diff_date_time = difftime(date, min(date), unit = "days")
  )
#> # A tibble: 23 x 5
#> # Groups:   area [3]
#>    PlotID species date                area  diff_date_time
#>    <chr>  <chr>   <dttm>              <chr> <drtn>        
#>  1 A      x       2-05-19 00:00:00    A         0 days    
#>  2 A      x1      2-08-19 00:00:00    A        92 days    
#>  3 B      x2      2-08-19 00:00:00    A        92 days    
#>  4 B      x4      3-05-19 00:00:00    A       365 days    
#>  5 B      x4      6-12-19 00:00:00    A      1675 days    
#>  6 A      x       26-05-19 00:00:00   A      8766 days    
#>  7 A      x       27-04-19 00:00:00   A      9101 days    
#>  8 B      x3      27-07-19 00:00:00   A      9192 days    
#>  9 A      x1      28-09-19 00:00:00   A      9620 days    
#> 10 B      x1      31-05-19 00:00:00   A     10592 days    
#> # … with 13 more rows

reprex package (v2.0.0) 于 2021-06-13 创建

【讨论】:

  • 谢谢,看起来很棒。不知道发生了什么,但是使用我的真实数据集,我只能在几秒钟内获得 diff_date_from_ 列?你有什么建议吗?
  • 我相信date 的数据类型在您的数据集中可能会有所不同。请提供dput(YOUR_DATA) 的输出。如果 YOUR_DATA 太大,dput(head(YOUR_DATA)) 就足够了。有了它,我们可以准确地看到您的数据的真实样子。将结果附加到问题的末尾。 (并在此处发表评论,以便我收到通知)
  • 感谢您的帮助@MarceloAvila - 我更新了我的问题,以便您可以看到我的日期在我的真实数据集中的格式。
【解决方案2】:

我用for 循环解决了这个问题

areas <- unique(df1$area)

df1$diffdate <- 0
for (i in 1:length(areas)){
  df1$diffdate[df1$area == areas[i]] <- df1$date[df1$area == areas[i]] - min(df1$date[df1$area == areas[i]])
}

【讨论】:

    【解决方案3】:

    对于每组area,您是否需要以 10 天为单位的日期序列?

    library(dplyr)
    library(tidyr)
    
    df1 %>% 
      arrange(PlotID, date, species) %>% 
      group_by(area) %>%
      complete(date = full_seq(date, 1)) %>%
      mutate(species = zoo::na.locf(species),
             PlotID = zoo::na.locf(PlotID),
             diffDate = 10*as.integer(date - first(date)) %/% 10) %>%
      ungroup() %>%
      group_by(diffDate) %>%
      filter(row_number() == 1)
    ## A tibble: 65 x 5
    ## Groups:   diffDate [65]
    #   area  date       PlotID species diffDate
    #   <chr> <date>     <chr>  <chr>      <dbl>
    # 1 A     1994-08-02 B      x2             0
    # 2 A     1994-08-12 B      x2            10
    # 3 A     1994-08-22 B      x2            20
    # 4 A     1994-09-01 B      x2            30
    # 5 A     1994-09-11 B      x2            40
    # 6 A     1994-09-21 B      x2            50
    # 7 A     1994-10-01 B      x2            60
    # 8 A     1994-10-11 B      x2            70
    # 9 A     1994-10-21 B      x2            80
    #10 A     1994-10-31 B      x2            90
    ## … with 55 more rows
    

    【讨论】:

    • 谢谢 - 但我想使用连续采样日期之间的实际天数差异,而不是 10 天序列...
    • @Conny 喜欢Marcelo's answer?如果不是,那里面有什么没有回答问题?
    • 我目前正试图让 Marcelo 的代码与我的真实数据集一起工作,但我得到的所有时间都在几秒钟内?不确定发生了什么,可能是日期格式的问题。所以还不确定,如果它按应有的方式工作。
    猜你喜欢
    • 2016-06-01
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 2019-09-30
    • 2021-07-26
    • 1970-01-01
    相关资源
    最近更新 更多