【问题标题】:Making groups of paired entries according to shared elements根据共享元素制作成对条目组
【发布时间】:2018-01-30 11:26:51
【问题描述】:

我是一名学生,试图分析增加印度北部地区掠食者杀死牲畜的可能性的因素。为此,我需要一个协变量列表,用于我的最终逻辑回归模型。我提出的问题与我的一个协变量有关 - 经常杀死牲畜的数量。 重复事件被定义为发生在 500 米以内且在前一次击杀的 7 天内发生的击杀事件。 (注意 - 强调preceding kill。这是因为一组重复事件可以延长超过 7 天或超过 500m 阈值,只要每次杀戮之间的间隔最多为 7 天或 500m) 我有一个数据集,其中包括以下内容 - 杀戮位置的 GPS 坐标、杀戮日期、捕食者和猎物物种。对于这个问题,只有杀死的日期和地点是相关的。 这是我的原始数据示例

    rawq <- structure(list(long = c(79.31957, 79.86758, 79.32283, 79.32253, 79.30502, 79.30047, 79.19935, 79.1984, 79.1984, 79.19318, 79.19247, 79.19243, 79.18512, 79.18333, 79.1541, 79.14438, 79.13998, 79.13538, 79.12522, 79.10168, 79.04163, 79.0405, 79.0364, 79.03505, 79.03473, 79.03428, 79.02517, 79.02458, 79.02428, 79.02265, 79.0197, 79.0197, 79.01967, 79.01965, 79.0193, 79.019, 79.01873, 79.0187, 79.0181, 79.01775, 79.00998, 79.00907, 79.00692, 79.00655, 79.0057, 79.00565, 79.00463, 79.00462, 79.00453, 79.00427, 79.0041, 79.00222, 79.00117, 79.00088, 79.00073, 78.9928, 78.9888, 78.98878, 78.98877, 78.9887, 78.98542, 78.98523, 78.9852, 78.98445, 78.97907, 78.9775, 78.9761, 78.97607, 78.97537, 78.97432, 78.97393, 78.97343, 78.97083, 78.95655, 78.9394, 78.92815, 78.92353, 78.92353, 78.92353, 78.92088, 78.92045, 78.91933, 78.91738, 78.90997, 78.90223, 78.90013, 78.90013, 78.88645, 78.8856, 78.8856, 78.8856, 78.88557, 78.86903, 78.86765, 78.85663, 78.8562, 78.85588, 78.8548, 78.83507, 78.80902), 
                           lat = c(29.3684, 29.35495, 29.39068, 29.3907, 29.34828, 29.30717, 29.26702, 29.25967, 29.25967, 29.2672, 29.25588, 29.25588, 29.46787, 29.34175, 29.42, 29.42098, 29.41918, 29.34048, 29.49228, 29.53947, 29.37597, 29.37652, 29.3591, 29.35055, 29.31765, 29.37003, 29.3125, 29.35305, 29.40163, 29.39007, 29.37155, 29.35098, 29.35515, 29.35517, 29.37277, 29.37068, 29.37345, 29.36962, 29.32252, 29.37657, 29.35432, 29.37653, 29.38792, 29.36958, 29.36803, 29.36808, 29.33892, 29.37277, 29.36908, 29.36773, 29.34068, 29.40667, 29.3076, 29.40875, 29.32183, 29.4093, 29.4075, 29.40742, 29.40738, 29.35965, 29.36952, 29.35965, 29.35967, 29.39118, 29.38528, 29.36535, 29.3598, 29.3598, 29.40777, 29.36418, 29.30988, 29.37605, 29.36813, 29.30137, 29.40247, 29.40767, 29.40455, 29.40455, 29.40455, 29.4092, 29.40532, 29.35217, 29.40328, 29.4023, 29.38242, 29.37243, 29.37243, 29.37205, 29.36975, 29.36975, 29.36975, 29.36972, 29.3721, 29.37023, 29.36867, 29.38953, 29.36808, 29.36865, 29.3841, 29.35162), 
        Cattle.sp. = structure(c(1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), 
        .Label = c("Boffalo(Calf)", "Buffalo", "Buffalo(Calf)", "BufFalo(Calf)", "Buffalo(S/A/)", "Bullack(S/A/)", "Bullock", "Bullock(S,A/)", "Bullock(S/A)", "Bullock(S/A/)", "Cow", "Cow (Calf)", "Cow(calf)", "Cow(Calf)", "Cow(S/A)", "Cow(S/A/)", "Horse"), class "factor"), 
        Predator = structure(c(1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), 
        .Label = c("Leopard", "Tiger"), class = "factor"), 
        Date = structure(c(16891, 17036, 17141, 17141, 16833, 16898, 16845, 16845, 16845, 17125, 17125, 17125, 17005, 17100, 17015, 16813, 16886, 17064, 17096, 16937, 17070, 17101, 17020, 17079, 17164, 16993, 16958, 17010, 17132, 17075, 17023, 17010, 16975, 16975, 16987, 17121, 17054, 17090, 16938, 16984, 16928, 16967, 16927, 16967, 17084, 16975, 16975, 16927, 16975, 16972, 16977, 16928, 17020, 17030, 16979, 16822, 17087, 17156, 17156, 17114, 16959, 17400, 17035, 17037, 17056, 16845, 16984, 16984, 16961, 16861, 17100, 17010, 17034, 16823, 17039, 16819, 16968, 16968, 16968, 16802, 16942, 17098, 16975, 16975, 16836, 17138, 17138, 16808, 16936, 16941, 16949, 16949, 16986, 16986, 16986, 16914, 16925, 16884, 17130, 17041), class = "Date")), 
        .Names = c("long", "lat", "Cattle.sp.", "Predator", "Date"), row.names = c(NA, 100L), class = "data.frame")

我使用以下代码,首先分别为距离和时间生成成对距离矩阵。我制作了一个表格 coloc.distance ,其中包含彼此距离小于 500m 的所有点对。然后我选择了时间少于 7 天的行。生成包含距离

    raw = read.csv("newraw.csv", header = T)
    library(measurements)
    library(fossil)                                    
    library(data.table)

    raw$Date <- as.Date(raw$Date)                            #formatting date


    a = as.matrix(dist(raw$Date))                              #generate pairwise distance matrix
    m <- as.matrix(earth.dist(raw))                             #pairwise distances

   sep.km <- 0.5                                               #threshold distance

   coloc.distance <- data.table(which(m<sep.km, arr.ind=T))    #choose 
   all pairs for which distance falls under threshold
   setnames(coloc.distance,c("row","col"),c("SD.1","SD.2"))    #adjust names
   coloc.distance <- coloc.distance[SD.1<SD.2,]                #lower triangular matrix
   coloc.distance[,dist:=m[SD.1,SD.2], by="SD.1,SD.2"] 
   coloc.distance[,time:=a[SD.1,SD.2], by="SD.1,SD.2"] 
   killsite <- data.table(id=as.integer(rownames(raw)),raw)
   setkey(coloc.distance,SD.1)
   coloc.distance[killsite,c("long.1","lat.1"):=list(long,lat)]
   setkey(coloc.distance,SD.2)
   coloc.distance[killsite,c("long.2","lat.2"):=list(long,lat)]
   setkey(coloc.distance, SD.1)
   coloc.distance[killsite, "date.1":=list(Date)]
   setkey(coloc.distance, SD.2)
   coloc.distance[killsite,"date.2" :=list(Date)]

   finalrows <- data.table(which(coloc.distance$time<7, arr.ind = T))

   final <- coloc.distance[finalrows$V1,]
   print(final)

我的问题是我不只是想要成对的重复事件。在某些情况下,有不止一个或两个重复事件。我需要一种将具有共享点的对分组的方法。 例如,如果我的代码返回以下对 -

[1,2][1,3][4,5][6,7][3,8]

我要分配的组是 [1,2,3,8] 和 [4,5]。是否有可以自动生成这些组的功能。很明显8也和1和2有关系,因为它和3有关系。

对于上面代码中的“最终”数据帧,这些是我希望收到的输出数据

这是代码为前 50 个条目生成的最终数据帧

final <- structure(list(SD.1 = c(3L, 8L, 11L, 33L, 35L, 46L, 44L, 46L, 49L, 47L, 58L), 
                        SD.2 = c(4L, 9L, 12L, 34L, 40L, 49L, 50L, 50L, 50L, 51L, 59L), 
                        dist = c(0.0291582094908988, 0, 0.00388155718182341, 0.00295090125908757, 0.448566716059333, 0.155426365139648, 0.301966362430361, 0.139316330866369, 0.152255819956674, 0.202390901062769, 0.00455334236486617), 
                        time = c(0, 0, 0, 0, 3, 0, 5, 3, 3, 2, 0), 
                        long.1 = c(79.32283, 79.1984, 79.19247, 79.01967, 79.0193, 79.00565, 79.00655, 79.00565, 79.00453, 79.00463, 78.98878), 
                        lat.1 = c(29.39068, 29.25967, 29.25588, 29.35515, 29.37277, 29.36808, 29.36958, 29.36808, 29.36908, 29.33892, 29.40742), 
                        long.2 = c(79.32253, 79.1984, 79.19243, 79.01965, 79.01775, 79.00453, 79.00427, 79.00427, 79.00427, 79.0041, 78.98877), 
                        lat.2 = c(29.3907, 29.25967, 29.25588, 29.35517, 29.37657, 29.36908, 29.36773, 29.36773, 29.36773, 29.34068, 29.40738), 
                        date.1 = structure(c(17141, 16845, 17125, 16975, 16987, 16975,16967, 16975, 16975, 16975, 17156), class = "Date"), 
                        date.2 = structure(c(17141, 16845, 17125, 16975, 16984, 16975, 16972, 16972, 16972, 16977, 17156), class = "Date")), 
                        .Names = c("SD.1", "SD.2", "dist", "time", "long.1", "lat.1", "long.2", "lat.2", "date.1", "date.2"), 
                        sorted = "SD.2", class = c("data.table", "data.frame"), row.names = c(NA, -11L))

如您所见,此表中有 11 对 -

[3,4] [8,9] [11,12] [33,34] [35,40] [46,49] [44,50] [46,50] [49,50] [47 ,51] [58,59]

一个足够的输出如下 -

[3,4] [8,9] [11,12] [33,34] [35,40] [44,46,49,50] [58,59]

在这个有限的数据集中,只有一组事件超过 2 个。当然,在我更大的集合中,还有更多。这只是最容易获得的一套。

【问题讨论】:

  • 你能为killsite对象提供一些数据吗?我可以将您的示例数据读取为一个名为raw 的对象,然后运行您的代码直到行coloc.distance[killsite,c("long.1","lat.1"):=list(long,lat)] 失败,因为找不到对象killsite
  • 糟糕。忘记在这里定义了。现在尝试运行代码。对此感到抱歉
  • 太棒了!您是否也可以将final &lt;- coloc.distance[final$V1,] 更改为final &lt;- coloc.distance[finalrows$V1,] 以使该位正常工作?
  • 您是否也可以更新您的示例数据,以便它实际生成具有您所描述问题的对?您当前的示例数据不返回任何具有共享值的对。
  • 全部完成。现在应该有足够的价值了。

标签: r grouping data-manipulation


【解决方案1】:

根据您的问题中提供的名为final 的数据集,这里有一种解决方案可以达到所需的输出。为了简单起见,我使用下划线来显示组合而不是列表样式。

我已在 final 数据框中将所需输出添加为名为 newgroup 的列,但您可以使用 dplyr::pull(newgroup) 将其作为向量取出。

首先,确定哪些网站出现了多次,因此应该进行分组。将这些存储在一个名为combo_group的向量中

library(magrittr)
library(dplyr)

combo_group <- 
    final %>% 
    filter(duplicated(SD.1) | duplicated(SD.1, fromLast = T) | duplicated(SD.2) | duplicated(SD.2, fromLast = T)) %>% 
    select(SD.1, SD.2) %>% 
    combine() %>% 
    unique() %>% 
    sort()

矢量看起来像这样:

combo_group
[1] 44 46 49 50

其次,创建newgroup 列,只要有行共享站点,就可以合并共享站点。

final %<>% 
    mutate(newgroup = ifelse(((SD.1 %in% combo_group)|(SD.2 %in% combo_group)), paste(combo_group, collapse = "_"), paste(SD.1, SD.2, sep = "_")))

这将返回一个名为 final 的数据框,其中包含 11 行和 11 列。相关变量如下所示:

final %>% select(SD.1, SD.2, newgroup)
   SD.1 SD.2    newgroup
1     3    4         3_4
2     8    9         8_9
3    11   12       11_12
4    33   34       33_34
5    35   40       35_40
6    46   49 44_46_49_50
7    44   50 44_46_49_50
8    46   50 44_46_49_50
9    49   50 44_46_49_50
10   47   51       47_51
11   58   59       58_59

【讨论】:

  • @DhruvModi 如果有多个共享站点组,我不确定此解决方案是否有效,但这是一个开始。如果需要,我可以更新这个答案,再次提供显示分组问题的示例数据。
  • 嘿,抱歉。我实际上更新了原始值“rawq”的初始集以包含扩展的条目列表。我不想过度拥挤数据集“最终”,因为我需要它来说明我的观点。扩展数据集似乎存在问题。不知道为什么会这样,但代码似乎将所有 combo_groups 组合成一个大组。我一开始用我的整个集合运行它,得到了一个巨大的组,所有的 combo_groups 合并在一起,而所有只有到站点的组都完好无损。
  • 我认为这可能是因为重复标准是通用的,并且扩展到包含一组下的大量数据,但后来我尝试了一组 100 个杀戮站点我手动将其分为两个组合组和 12 对。相反,我得到了一个由两个组合组和 12 对组成的大组。
  • 感谢您的帮助
  • @DhruvModi 啊,我原以为会发生这种情况。我认为这需要一个定制的功能来获取不同的组合,然后分配它们。今天晚些时候我会进一步考虑。同时,这是我的一个问题,有点相似并有解决方案:stackoverflow.com/questions/43009055/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-14
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多