- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想根据地址和包裹的所有权将个人分组到不同的家庭。如果人们住在同一地址,并且如果他们直接或间接地通过至少一个地 block 的所有权联系在一起,那么他们就属于同一家庭。
个人之间的联系可以是直接,即两个人有一个共同的包裹。但是链接也可以是间接的,通过交叉链接形成链 - 两个人有一个共同的包裹,其中一个人与其他人有一个共同的包裹,并且都住在同一个地址。
这里有一些例子:
我有三个变量:地址 ID、所有者 ID 和包裹 ID。我想得到一个家庭号码。这是一个示例表:
id_address id_owner id_parcel id_household
A 1 m 1
A 1 n 1
A 2 n 1
A 2 o 1
A 3 o 1
A 4 p 2
A 5 q 3
B 6 s 4
B 7 r 5
B 8 r 5
C 9 s 6
D 10 t 7
E 11 u 8
E 11 v 8
F 12 w 9
F 13 w 9
我的第一直觉是循环,但我有 800,000 行,这可能需要很长时间。
示例数据,其中“id_household”是我要创建的变量:
structure(list(id_address = c("A", "A", "A", "A", "A", "A", "A",
"B", "B", "B", "C", "D", "E", "E", "F", "F"), id_owner = c(1L,
1L, 2L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 11L, 12L, 13L
), id_parcel = c("m", "n", "n", "o", "o", "p", "q", "s", "r",
"r", "s", "t", "u", "v", "w", "w"), id_household = c(1L, 1L,
1L, 1L, 1L, 2L, 3L, 4L, 5L, 5L, 6L, 7L, 8L, 8L, 9L, 9L)), class = "data.frame", row.names = c(NA,
-16L))
最佳答案
您的问题可能会被视为图形问题。 igraph
包提供了极好的工具。 'id_owner' 和 'id_parcel' 列可以视为边列表。 components
函数提供“每个顶点所属的簇 ID”。我使用 data.table
进行一般数据处理。
library(data.table)
library(igraph)
setDT(d)
d2 = d[ , {
# create graph. columns id_owner and id_parcel are treated as an edge list.
g = graph_from_data_frame(.SD)
# get components of the graph that are directly or indirectly connected
mem = components(g)$membership
# grab the memberships and their names (i.e. the vertices)
.(id_parcel = names(mem), mem = mem)
# do the above for each id_address
}, by = id_address]
# join the memberships to the original data
# paste with id_address for uniqueness
d[d2, on = .(id_address, id_parcel), id := paste0(id_address, mem)]
# if you want a consecutive integer as 'id', to make it agree with 'id_household'
d[ , id2 := as.integer(as.factor(id))]
输出:
d
# id_address id_owner id_parcel id_household id id2
# 1: A 1 m 1 A1 1
# 2: A 1 n 1 A1 1
# 3: A 2 n 1 A1 1
# 4: A 2 o 1 A1 1
# 5: A 3 o 1 A1 1
# 6: A 4 p 2 A2 2
# 7: A 5 q 3 A3 3
# 8: B 6 s 4 B1 4
# 9: B 7 r 5 B2 5
# 10: B 8 r 5 B2 5
# 11: C 9 s 6 C1 6
# 12: D 10 t 7 D1 7
# 13: E 11 u 8 E1 8
# 14: E 11 v 8 E1 8
# 15: F 12 w 9 F1 9
# 16: F 13 w 9 F1 9
避免 by
操作的替代方案。另一方面增加了一些其他的步骤,所以是否更高效取决于数据的结构。
首先,创建“复合变量”,其中地址分别与包裹和所有者连接。创建成员资格
。通过拆分名称检索原始列 (tstrsplit(names(mem), "_", fixed = TRUE)
)。加入成员(member)资格到原始数据
d[ , `:=`(
address_parcel = paste(id_address, id_parcel, sep = "_"),
address_owner = paste(id_address, id_owner, sep = "_"))]
d2 = d[ , {
g = graph_from_data_frame(.SD[ , .(address_owner, address_parcel)])
mem = components(g)$membership
c(tstrsplit(names(mem), "_", fixed = TRUE), .(mem = mem))
}]
d[d2, on = c(id_address = "V1", id_parcel = "V2"), id_hh := mem]
输出:
d
# id_address id_owner id_parcel id_household id_hh
# 1: A 1 m 1 1
# 2: A 1 n 1 1
# 3: A 2 n 1 1
# 4: A 2 o 1 1
# 5: A 3 o 1 1
# 6: A 4 p 2 2
# 7: A 5 q 3 3
# 8: B 6 s 4 4
# 9: B 7 r 5 5
# 10: B 8 r 5 5
# 11: C 9 s 6 6
# 12: D 10 t 7 7
# 13: E 11 u 8 8
# 14: E 11 v 8 8
# 15: F 12 w 9 9
# 16: F 13 w 9 9
对较大数据(原始数据重复 1e4
次并在每个 block 中创建新 ID)计时两个备选方案。对于此特定数据,避免 by
的第二种选择的速度大约快 100 倍。
# prepare toy data
d1 = as.data.table(d)
n = 1e4
dL = d1[rep(1:.N, n)]
# make unique id within the repeated data frames
dL[ , `:=`(
id_address = paste(rep(1:n, each = nrow(d1)), sep = ".", id_address),
id_owner = paste(rep(1:n, each = nrow(d1)), sep = ".", id_owner),
id_parcel = paste(rep(1:n, each = nrow(d1)), sep = ".", id_parcel)
)]
备选方案 1:通过
地址
dL1 = copy(dL)
system.time({
d2 = dL1[ , {
g = graph_from_data_frame(.SD)
mem = components(g)$membership
.(id_parcel = names(mem), mem = mem)
}, by = id_address]
dL1[d2, on = .(id_address, id_parcel), id_hh := paste(id_address, mem, sep = "_")]
})
# user system elapsed
# 59.46 7.68 67.11
备选方案 2. 复合变量和拆分:
dL2 = copy(dL)
system.time({
dL2[ , `:=`(
address_parcel = paste(id_address, id_parcel, sep = "_"),
address_owner = paste(id_address, id_owner, sep = "_"))]
d3 = dL2[ , {
g = graph_from_data_frame(.SD[ , .(address_owner, address_parcel)])
mem = components(g)$membership
c(tstrsplit(names(mem), "_", fixed = TRUE), .(mem = mem))
}]
dL2[d3, on = c(id_address = "V1", id_parcel = "V2"), id_hh := mem]
})
# user system elapsed
# 0.47 0.24 0.57
相等性测试:
all.equal(as.integer(as.factor(stringi::stri_pad_left(dL1$id_hh, 9, "0"))),
dL2$id_hh)
# TRUE
关于r - 根据直接和间接关系对个人进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68581080/
您好,我正在处理 BIRT 报告。我有一个查询,我必须对父级的重复数据进行分组,但子级也不能分组! 在我的查询中: item 是父项,item_ledger_entry 是子项。我有来自 item.N
我正在使用 GA API。 这是针对 MCF 目标报告(底部)的标准目标完成指标表(顶部) 看一下这个: 总数加起来 (12,238),但看看按 channel 分组的分割有多么不同!我以为这些会很接
我正在开发一个流量计数器,我想获得 IP 和重复计数,但是如何? 就像是 :select ip, count(ip) from Redirect 返回 : null total ip count 重定
我尝试编写一个正则表达式来匹配条件表达式,例如: a!=2 1+2=2+a 我尝试提取运算符。我当前的正则表达式是“.+([!=<>]+).+” 但问题是匹配器总是尝试匹配组中可能的最短字符串
在 MS Transact SQL 中,假设我有一个这样的表(订单): Order Date Order Total Customer # 09/30/2008 8
我想按 m.ID 分组,并对每个 m.id 求和 (pm.amount_construction* prod.anzahl) 实际上我有以下结果: Meterial_id | amount_const
我想根据多列中的值对值进行分组。这是一个例子: 我想得到输出: {{-30,-50,20},{-20,30,60},{-30,NULL or other value, 20}} 我设法到达: SELE
我正在尝试找出运行此查询的最佳方式。我基本上需要返回在我们的系统中只下了一个订单的客户的“登录”字段列表(登录字段基本上是客户 ID/ key )。 我们系统的一些背景...... 客户在同一日期下的
给定以下mysql结果集: id code name importance '1234', 'ID-CS-B', 'Chocolate Sauce'
大家好,我的数据框中有以下列: LC_REF 1 DT 16 2C 2 DT 16 2C 3 DT 16 2C 1 DT 16 3C 6 DT 16 3C 3
我有这样的 mongoDB 集合 { "_id" : "EkKTRrpH4FY9AuRLj", "stage" : 10, }, { "_id" : "EkKTRrpH4FY9
假设我有一组数据对,其中 index 0 是值,index 1 是类型: input = [ ('11013331', 'KAT'), ('9085267',
java中用stream进行去重,排序,分组 一、distinct 1. 八大基本数据类型 List collect = ListUtil.of(1, 2, 3, 1, 2).stream().fil
基本上,我从 TABLE_A 中的这个开始 France - 100 France - 200 France - 300 Mexico - 50 Mexico - 50 Mexico - 56 Pol
我希望这个正则表达式 ([A-Z]+)$ 将选择此示例中的最后一次出现: AB.012.00.022ABC-1 AB.013.00.022AB-1 AB.014.00.022ABAB-1 但我没有匹配
我创建了一个数据透视表,但数据没有组合在一起。 任何人都可以帮助我获得所需的格式吗? 我为获取数据透视表而编写的查询: DECLARE @cols AS NVARCHAR(MAX), -- f
我想按时间段(月,周,日,小时,...)选择计数和分组。例如,我想选择行数并将它们按 24 小时分组。 我的表创建如下。日期是时间戳。 CREATE TABLE MSG ( MSG_ID dec
在 SQL Server 2005 中,我有一个包含如下数据的表: WTN------------Date 555-111-1212 2009-01-01 555-111-1212 2009-
题 假设我有 k 个标量列,如果它们沿着每列彼此在一定距离内,我想对它们进行分组。 假设简单 k 是 2 并且它们是我唯一的列。 pd.DataFrame(list(zip(sorted(choice
问题 在以下数据框中 df : import random import pandas as pd random.seed(999) sz = 50 qty = {'one': 1, 'two': 2
我是一名优秀的程序员,十分优秀!