r语言 - 合并重复的变量,同时保留新列中的唯一值



我有一个适度的标签返回数据集,其中个体用唯一的标签号(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分解为一个列表,每个元素作为其中一行。然后将它们绑定以创建一个宽的数据帧。所有这些结果数据帧然后被重新绑定

最新更新