我有一个适度的标签返回数据集,其中个体用唯一的标签号(TagNo)区分。其中一些个体已经被多次重新捕获,但是我们报告数据的方式是,每个重新捕获实例最终都是单独的一行。下面的代码应该会重现我的数据集的前十行。我想结束每个TagNo一行与新列的每次发生的recap_date(例如,recap_date, recap_date_2, recap_date_3等),其中recap_date是最早的日期,recap_date_2将是下一个时间顺序的日期,等等。我希望类似于TL.y, LAT和LONG的东西,除了这些值需要对应于正确的recap_date(例如,如果recap_date为"2013-06-28")。是一个给定TagNo的recap_date_2;TL.y_2、LAT_2和LONG_2需要是对应于TagNo的recap_date的TL.y、LAT和LONG)。显然,被重新捕获两次的个体不会有recap_date_3的值,而NA在该实例中是可接受的值。
我尝试过pivot_wider()
和其他长到宽的转换,但据我所知,我的数据已经很宽了。我也搜索了这么广泛,还没能找到一个解决方案。不可否认,这可能是由于我的搜索方法中的操作错误!我觉得for
循环可能是一个解决方案,但我对这方面的知识不够了解,大多数例子都是针对非常简单的问题。任何帮助都会很感激。希望它清楚我在寻找什么!
structure(list(TagNo = c("EC50249", "EC50249", "EC50249", "EC50249",
"EC52114", "EC52114", "EC52411", "EC52411", "EC60203", "EC60203"
), Species = c("Red grouper", "Red grouper", "Red grouper", "Red grouper",
"Red grouper", "Red grouper", "Red grouper", "Red grouper", "Red grouper",
"Red grouper"), TL.y = c(11.5, 16, 14, 15, 16, 17, NA, 15, 17,
12), YR = c(2013L, 2013L, 2013L, 2013L, 2016L, 2016L, 2016L,
2016L, 2016L, 2016L), recap_date = c("2013-04-20", "2013-06-28",
"2014-04-06", "2014-04-12", "2016-04-12", "2016-05-04", "2016-05-06",
"2017-01-20", "2016-04-04", "2016-04-12"), LAT = c("24 42", "24 42",
"24 41", "24 43", "26 05", "26 05", "24 39", "24 39", "26 05",
"26 05"), LONG = c("80 53", "80 53", "80 58", "80 54", "80 05",
"80 05", "81 01", "81 02", "80 05", "80 05")), row.names = c(NA,
10L), class = "data.frame")
欢迎来到SO!不是很清楚,但是你可以使用tidyverse:
来管理它。# some libraries
library(dplyr)
library(tidyr)
# your data
df %>%
# make date as date
mutate(recap_date = as.Date(recap_date, '%Y-%m-%d')) %>%
# sort by TagNo and date
arrange(TagNo, recap_date) %>%
# group by tag no to...
group_by(TagNo) %>%
# ... add by group an id that is going to be helpful to...
mutate(id = row_number()) %>%
# ...make your data wider
pivot_wider(names_from = id,
values_from = c(recap_date, TL.y, YR, LAT, LONG))
# A tibble: 4 x 22
# Groups: TagNo [4]
TagNo Species recap_date_1 recap_date_2 recap_date_3 recap_date_4 TL.y_1 TL.y_2 TL.y_3 TL.y_4 YR_1 YR_2 YR_3 YR_4 LAT_1
<chr> <chr> <date> <date> <date> <date> <dbl> <dbl> <dbl> <dbl> <int> <int> <int> <int> <chr>
1 EC50~ Red gr~ 2013-04-20 2013-06-28 2014-04-06 2014-04-12 11.5 16 14 15 2013 2013 2013 2013 24 42
2 EC52~ Red gr~ 2016-04-12 2016-05-04 NA NA 16 17 NA NA 2016 2016 NA NA 26 05
3 EC52~ Red gr~ 2016-05-06 2017-01-20 NA NA NA 15 NA NA 2016 2016 NA NA 24 39
4 EC60~ Red gr~ 2016-04-04 2016-04-12 NA NA 17 12 NA NA 2016 2016 NA NA 26 05
# ... with 7 more variables: LAT_2 <chr>, LAT_3 <chr>, LAT_4 <chr>, LONG_1 <chr>, LONG_2 <chr>, LONG_3 <chr>, LONG_4 <chr>
我认为这是一个解决方案:
library(data.table)
library(plyr)
dlply( x, "TagNo", function(d) {
cols <- setdiff( colnames(d), c("TagNo","Species") )
l <- lapply( 1:nrow(d), function(i) {
r <- d[i,cols]
if( i > 1 ) {
names(r) <- paste0( names(r), "_", i )
}
r
})
do.call( cbind, l )
}) %>% rbindlist(fill=TRUE)
你在正确的轨道上。该解决方案迭代TagNo,将子data.frame分解为一个列表,每个元素作为其中一行。然后将它们绑定以创建一个宽的数据帧。所有这些结果数据帧然后被重新绑定