R 中的 Pivot table:创建一个新数据框并使用逻辑语句从现有数据框填充它

Pivot table in R: create a new data frame and populate it from an existing data frame using logical statements

排名新手,感谢指点。我需要构建一个“遭遇历史”来输入程序 MARK。它必须是一个文本文件,看起来像这样的 150 行:

/*aaam*/ 100101111101000000000 0 1 1;  
/*ayym*/ 100000001101000000000 0 1 1;  
/*bbbm*/ 100000000001111111110 1 0 1; 

左边的四个字母代码是研究中鸟类的个体标识符。中间的一串 0 和 1 是关键部分:1 表示在给定时间段内遇到了鸟,0 表示没有遇到。尾随的“0 1 1;”或“1 0 1;”分别表示“女性”或“男性”,空格和分号、斜杠和星号是必需的。翻译成英文,最上面一行写着“这只叫aaam的鸟是雌鸟,第一次遇到(2018年3月到6月),第二次没遇到(2018年7月到10月),第三次没遇到间隔(2018 年 11 月至 2019 年 2 月),依此类推共 21 个时间间隔。

我有一个名为“resightings”的现有数据框,大约有 5000 行和 24 列,看起来像这样(省略了许多列),我需要从中提取遭遇历史:

BIRD YEAR MONTH DAY SURVEY_TYPE OUTCOME
aaam 2018 3 5 4 2
aaam 2018 6 12 1 1
aaam 2019 1 12 1 0
ayym 2018 4 4 4 3
ayym 2018 6 16 1 1
bbbm 2018 6 19 1 1

同样,BIRD 的四个字母代码用于标识独特的个体。每行是一个观察;每只鸟有 1 到 100 多条线。这些观察告诉我遇到每只鸟的时间:例如,如果存在一行,其中 BIRD 是 aaam,YEAR 是 2018,MONTH 是 3,OUTCOME 是 1,这意味着 aaam 是在 2018 年 3 月遇到的,并且中的第一个数字aaam 的遭遇历史为 1,但如果再瞄准数据库中没有任何行符合适当的标准,则没有遇到这只鸟,因此该时间段为零。

要从大数据框获取“遭遇历史”,我需要:

我尝试过的:

unique(resightings$BIRD)

returns 一个向量,每个鸟的名字都是独一无二的。

像下面这样的语句returns“真”或“假”,如果我能让它吐出“1”或“0”,我想我可以用这样的东西来填充在其他列中,编辑我如何为每个时间间隔指定月份和年份。

any(resightings$BIRD=="ayym" & resightings$YEAR==2018 & resightings$MONTH==12|11|10|9 & resightings$OUTCOME==1)

我认为“粘贴”将是我将最终数据框的每一行转换为文本字符串的方式,可能使用 sep="" 以避免插入空格。

但我对如何从旧数据框构建新的较小数据框的其余部分非常困惑,甚至是如何将其概念化。我是否构建一个空白 table 然后填充它?我是否使用 unique(resightings$BIRD) 产生的向量为每个新列构造额外的向量,然后 assemble 所有这些向量进入数据框?我为我的新手道歉。我已经阅读了大多数关于 pivot tables 或“从 R 中现有 table 中的数据构建新的 table”的问题的答案,但我仍然卡住了。

有趣的任务...这是一种可能的解决方案:

library(tidyverse)

# Test data
data <- tribble(
    ~BIRD,~YEAR,~MONTH,~DAY,~SURVEY_TYPE,~OUTCOME,~SEX,
    "aaam",2018,3,5,4,2,"male",
    "aaam",2018,6,12,1,1,"male",
    "aaam",2019,1,12,1,0,"male",
    "ayym",2018,4,4,4,3,"female",
    "ayym",2018,6,16,1,1,"female",
    "bbbm",2018,6,19,1,1,"male",
    "bbbm",2019,2,19,1,1,"male"
)

data2 <- data %>% group_by(BIRD) %>% summarise(
    PERIOD_1 = as.integer(any(YEAR==2018 & MONTH %in% c(1,2,3,4) & OUTCOME==1)),
    PERIOD_2 = as.integer(any(YEAR==2018 & MONTH %in% c(5,6,7,8) & OUTCOME==1)),
    PERIOD_3 = as.integer(any(YEAR==2018 & MONTH %in% c(9,10,11,12) & OUTCOME==1)),
    PERIOD_4 = as.integer(any(YEAR==2019 & MONTH %in% c(1,2,3,4) & OUTCOME==1)),
    SEX = if (unique(SEX)=="male") "1 0 1" else "0 1 1"
)
data2

data3 <- data2 %>% unite("HISTORY", PERIOD_1:PERIOD_4, sep="")
data4 <- paste0("/*", data3$BIRD, "*/ ", data3$HISTORY, " ", data3$SEX, ";")
write_lines(data4, "test.inp")
data4