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,但如果再瞄准数据库中没有任何行符合适当的标准,则没有遇到这只鸟,因此该时间段为零。
要从大数据框获取“遭遇历史”,我需要:
- 构建一个新的数据框,其中第一列也是鸟类名称,但每只鸟类只有一行。
- 添加大约 21 个额外的列,其中大部分将根据逻辑测试填充 0 或 1,例如上面的“if”语句(请参阅下面以“any”开头的代码)。
- 将各种空格、斜杠、星号、性别代码添加到每一行,如顶部示例所示,
- 将每一行,所有这些 1、0、空格、字母和字符连接成一个文本字符串,
- 另存为文本文件(最好使用后缀“.inp”,但我也可以在 R 之外重命名)。
我尝试过的:
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
排名新手,感谢指点。我需要构建一个“遭遇历史”来输入程序 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,但如果再瞄准数据库中没有任何行符合适当的标准,则没有遇到这只鸟,因此该时间段为零。
要从大数据框获取“遭遇历史”,我需要:
- 构建一个新的数据框,其中第一列也是鸟类名称,但每只鸟类只有一行。
- 添加大约 21 个额外的列,其中大部分将根据逻辑测试填充 0 或 1,例如上面的“if”语句(请参阅下面以“any”开头的代码)。
- 将各种空格、斜杠、星号、性别代码添加到每一行,如顶部示例所示,
- 将每一行,所有这些 1、0、空格、字母和字符连接成一个文本字符串,
- 另存为文本文件(最好使用后缀“.inp”,但我也可以在 R 之外重命名)。
我尝试过的:
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