r - 如何让 R 逐行搜索大型数据集以查找两列之一中是否存在值,然后在数据丢失时返回一个值

标签 r dataframe

所以我对 R 还很陌生,并且多年来一直在处理一个非常大的树木生长/死亡率数据集。由于死亡率并不总是正确记录,我需要搜索每一行的测量值(可以是胸高直径 (DBH) 或地高直径 (DGH)),然后,如果它们在最近一次调查之前停止,则有 R记录他们停止的年份,以便我可以计算出每年发生的推定死亡人数。我称之为死亡率的数据框的结构如下:

year  plant.id  dbh  dgh  
1        1      3.2  na
2        1      3.3  na
3        1      3.5  na
4        1      3.6  na
1        2      na   1.0
2        2      na   1.1
3        2      na   na
4        2      na   na

我希望能够添加一列或类似的内容,然后给出给定植物“死亡”的年份,这样就可以很容易地计算数据集中该年的所有实例。像这样的事情会很棒:

year  plant.id  dbh  dgh   mort.year
1        1      3.2  na       na
2        1      3.3  na       na
3        1      3.5  na       na
4        1      3.6  na       na
1        2      na   1.0      na
2        2      na   1.1      na
3        2      na   na       3
4        2      na   na       3
1        3      2.2  na       na
2        3      2.3  na       na
3        3      2.4  na       na
4        3      na   na       4

由于以下原因,情况变得更加复杂:1)新植物生长并在以后的几年中添加,2)偶尔会错误地认为一棵树已死亡或丢失,因此当年没有进行测量,然后在随后的几年中,树实际上被发现是活的。结果数据如下所示:

year  plant.id  dbh  dgh
1        4      na   na 
2        4      na   1.0 
3        4      na   1.0 
4        4      na   1.1 
1        5      2.1   na
2        5      na    na
3        5      2.2   na
4        5      2.2   na

出于死亡率估计的目的,我基本上想忽略这些(除非他们后来死亡),所以理想的结果是这样的:

year  plant.id  dbh  dgh   mort.year
1        4      na   na       na
2        4      na   1.0      na
3        4      na   1.0      na
4        4      na   1.1      na
1        5      2.1   na      na
2        5      na    na      na
3        5      2.2   na      na
4        5      2.2   na      na

我大致知道如何让 R 计算给定年份的所有实例以获得最终结果,我的主要挑战是弄清楚我可以使用哪些命令/逻辑来让它进行搜索,然后生成一列像这样,所以任何有关如何做到这一点的提示/建议将不胜感激!

最佳答案

这是一种使用 data.table 的方法,希望它会很快:

library(data.table)
setDT(mortality)
setkey(mortality,plant.id,year)
mortality[, .(mort.year = 
              year[dbh == "na" &
                   dgh == "na" & 
                   cumsum((dbh != "na" | dgh != "na")) == max(cumsum((dbh != "na" | dgh != "na")))]),
                   by = plant.id][,.(mort.year = min(mort.year)), by = plant.id]
   plant.id mort.year
1:        2         3
2:        3         4

这适用于 3 个简单的逻辑比较。

  1. dbh == "na"(注意,如果值为 NA 而不是 ,请将其替换为 is.na”呐”)
  2. dgh == "na"
  3. 观测到测量的年数必须等于曾经进行过测量的最大年数。

可视化它可能会更容易理解:

 mortality[, temp := cumsum((dbh != "na" | dgh != "na")), by = plant.id][]
    year plant.id dbh dgh temp
 1:    1        1 3.2  na    1
 2:    2        1 3.3  na    2
 3:    3        1 3.5  na    3
 4:    4        1 3.6  na    4
 5:    1        2  na 1.0    1
 6:    2        2  na 1.1    2
 7:    3        2  na  na    2
 8:    4        2  na  na    2
 9:    1        3 2.2  na    1
10:    2        3 2.3  na    2
11:    3        3 2.4  na    3
12:    4        3  na  na    3
13:    1        4  na  na    0
14:    2        4  na 1.0    1
15:    3        4  na 1.0    2
16:    4        4  na 1.1    3
17:    1        5 2.1  na    1
18:    2        5  na  na    1
19:    3        5 2.2  na    2
20:    4        5 2.2  na    3

由于 NA 和双 min 返回之间的类型不一致,min 调用必须分开。 setkey 调用可确保年份排序正确。

如果需要,可以通过简单的连接来创建列:

result <- mortality[, .(mort.year = year[dbh == "na" & dgh == "na" & cumsum((dbh != "na" | dgh != "na")) == max(cumsum((dbh != "na" | dgh != "na")))]), by = plant.id][,.(mort.year = min(mort.year)), by = plant.id]

result[mortality,][, mort.year := fifelse(dbh == "na" & dgh == "na", mort.year, NA_integer_)][]
    plant.id mort.year year dbh dgh
 1:        1        NA    1 3.2  na
 2:        1        NA    2 3.3  na
 3:        1        NA    3 3.5  na
 4:        1        NA    4 3.6  na
 5:        2        NA    1  na 1.0
 6:        2        NA    2  na 1.1
 7:        2         3    3  na  na
 8:        2         3    4  na  na
 9:        3        NA    1 2.2  na
10:        3        NA    2 2.3  na
11:        3        NA    3 2.4  na
12:        3         4    4  na  na
13:        4        NA    1  na  na
14:        4        NA    2  na 1.0
15:        4        NA    3  na 1.0
16:        4        NA    4  na 1.1
17:        5        NA    1 2.1  na
18:        5        NA    2  na  na
19:        5        NA    3 2.2  na
20:        5        NA    4 2.2  na

关于r - 如何让 R 逐行搜索大型数据集以查找两列之一中是否存在值,然后在数据丢失时返回一个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62353298/

相关文章:

php - 通过 Python/R/任何外部程序在 Apache/PHP 中启用临时文件创建和使用 - 最佳选择

r - 在 R 中,错误 "need at least one panel"是什么意思,如何解决?

r - 使用 dplyr 对多列求和

python - 如何从数据框的列中获取唯一名称

r - 基于一个列模态和其他列的新列

r - 当分隔字符位于字符串中时,将字符向量拆分为数据帧

R输入文件阿拉伯语?

r - 基于另一个输入约束 Shiny 的应用程序输入

python - 数据框:条件替换

r - 如何在 R 中的 df 中添加每个日期的时间段