查找具有相同值的唯一密钥对
Finding the unique key pair with same values
我正在尝试为以下问题找到解决方案,但无法找到解决方案,请帮助我解决逻辑问题,我也可以确定方向,我可以编码但无法提出必要的逻辑。
这是问题所在:
我有这样一个数据集:
df <- data.frame(x = c(1, 1, 2, 2, 2, 2, 3, 4, 5, 1, 2,3, 4, 7, 8, 9, 4, 10, 10, 11, 12), y = c('a', 'b', 'c','d', 'e', 'f', 'a', 'a', 'e', 'k', 'l', 'm', 'n', 'b', 'e', 'e', 'b', 'x', 'y', 'z', 'z' ))
预期的输出应该是:
col1 col2
1 1,4,3, 7
2 2,5,8,9
10 10
11 11, 12
逻辑:将 x 列视为键,将 y 列视为值,现在如果使用不同的 value(y) 值重复键,则所有这些键都连接在一起,作为
示例:1 与 a 和 b、k 相连,但 a 也与 4,3、7 相连。现在 2 与 c d e 和 f 相连,因此 2、5、8、9 也类似地与 z 与 11 相连和 12. 为了建立最终连接,我们可以将它们连接在一起并取出第一个键作为键,其余为逗号分隔值。
我的尝试
library(data.table)
setDT(df)
setnames(df, c('x', 'y'),c('los', 'mob'))
dfLos <- df[, .(mobconcat = paste0(mob, collapse = ',')), .(los)]
dfMob <- df[, .(losconcat = paste0(los, collapse = ',')), .(mob)]
df <- merge(df, dfMob, by='mob', all.x=TRUE)
dim(df)
df <- merge(df, dfLos, by='los', all.x=TRUE)
(showing only few rows)
los mob losconcat mobconcat
1: 1 a 1,3,4 a,b,k
2: 1 b 1,7,4 a,b,k
3: 1 k 1 a,b,k
4: 2 c 2 c,d,e,f,l
5: 2 d 2 c,d,e,f,l
6: 2 e 2,5,8,9 c,d,e,f,l
7: 2 f 2 c,d,e,f,l
8: 2 l 2 c,d,e,f,l
现在我被困在这里,可能是这种方法是浪费,我在这里尝试的方法是用逗号分隔所有键来获取所有键,但无法理解如何进一步实现。
非常感谢。欢迎您提出任何其他方法或扩展我的方法,我对任何人都满意。
这是一个可以满足您要求的函数。它可能不是最快或最优雅的答案...
key_connect <- function(data, key, val) {
val_by_key <- split(data[[val]], data[[key]])
key_by_val <- split(data[[key]], data[[val]])
f <- function(val) unique(unlist(key_by_val[val]))
res <- data.frame(
## Unique keys
key = as.integer(names(val_by_key)),
## Connected keys with duplicates
key_con = I(lapply(val_by_key, f))
)
ul <- unlist(res[["key_con"]], use.names = FALSE)
ends <- cumsum(lengths(res[["key_con"]]))
ends <- c(0L, ends[-length(ends)])
g <- function(i, end) i[match(i, ul[seq_len(end)], 0L) == 0L]
## Connected keys without duplicates
res[["key_con"]] <- Map(g, i = res[["key_con"]], end = ends)
res <- res[lengths(res[["key_con"]]) > 0L, ]
row.names(res) <- NULL
res
}
key_connect(df, key = "x", val = "y")
key key_con
1 1 1, 3, 4, 7
2 2 2, 5, 8, 9
3 10 10
4 11 11, 12
另一个不是很漂亮的解决方案,但它是基于 data.table 的。也许有帮助。
library(data.table)
library(stringr)
df = data.table(x = c(1, 1, 2, 2, 2, 2, 3, 4, 5, 1, 2,3, 4, 7, 8, 9, 4, 10, 10, 11, 12), y = c('a', 'b', 'c','d', 'e', 'f', 'a', 'a', 'e', 'k', 'l', 'm', 'n', 'b', 'e', 'e', 'b', 'x', 'y', 'z', 'z' ))
df2 = df[, .(conc = str_c(x, collapse = ", ")), by=y]
df3 = merge(df, df2, by="y", all=TRUE)
df4 = unique(df3[, .(conc = unlist(strsplit(str_c(conc, collapse = ", "), ", "))), by=x][order(conc)], by="conc")
df_final = df4[, .(conc = str_c(conc, collapse = ", ")), by=x][order(x)]
输出:
x conc
1: 1 1, 3, 4, 7
2: 2 2, 5, 8, 9
3: 10 10
4: 11 11, 12
我正在尝试为以下问题找到解决方案,但无法找到解决方案,请帮助我解决逻辑问题,我也可以确定方向,我可以编码但无法提出必要的逻辑。
这是问题所在:
我有这样一个数据集:
df <- data.frame(x = c(1, 1, 2, 2, 2, 2, 3, 4, 5, 1, 2,3, 4, 7, 8, 9, 4, 10, 10, 11, 12), y = c('a', 'b', 'c','d', 'e', 'f', 'a', 'a', 'e', 'k', 'l', 'm', 'n', 'b', 'e', 'e', 'b', 'x', 'y', 'z', 'z' ))
预期的输出应该是:
col1 col2
1 1,4,3, 7
2 2,5,8,9
10 10
11 11, 12
逻辑:将 x 列视为键,将 y 列视为值,现在如果使用不同的 value(y) 值重复键,则所有这些键都连接在一起,作为 示例:1 与 a 和 b、k 相连,但 a 也与 4,3、7 相连。现在 2 与 c d e 和 f 相连,因此 2、5、8、9 也类似地与 z 与 11 相连和 12. 为了建立最终连接,我们可以将它们连接在一起并取出第一个键作为键,其余为逗号分隔值。
我的尝试
library(data.table)
setDT(df)
setnames(df, c('x', 'y'),c('los', 'mob'))
dfLos <- df[, .(mobconcat = paste0(mob, collapse = ',')), .(los)]
dfMob <- df[, .(losconcat = paste0(los, collapse = ',')), .(mob)]
df <- merge(df, dfMob, by='mob', all.x=TRUE)
dim(df)
df <- merge(df, dfLos, by='los', all.x=TRUE)
(showing only few rows)
los mob losconcat mobconcat
1: 1 a 1,3,4 a,b,k
2: 1 b 1,7,4 a,b,k
3: 1 k 1 a,b,k
4: 2 c 2 c,d,e,f,l
5: 2 d 2 c,d,e,f,l
6: 2 e 2,5,8,9 c,d,e,f,l
7: 2 f 2 c,d,e,f,l
8: 2 l 2 c,d,e,f,l
现在我被困在这里,可能是这种方法是浪费,我在这里尝试的方法是用逗号分隔所有键来获取所有键,但无法理解如何进一步实现。
非常感谢。欢迎您提出任何其他方法或扩展我的方法,我对任何人都满意。
这是一个可以满足您要求的函数。它可能不是最快或最优雅的答案...
key_connect <- function(data, key, val) {
val_by_key <- split(data[[val]], data[[key]])
key_by_val <- split(data[[key]], data[[val]])
f <- function(val) unique(unlist(key_by_val[val]))
res <- data.frame(
## Unique keys
key = as.integer(names(val_by_key)),
## Connected keys with duplicates
key_con = I(lapply(val_by_key, f))
)
ul <- unlist(res[["key_con"]], use.names = FALSE)
ends <- cumsum(lengths(res[["key_con"]]))
ends <- c(0L, ends[-length(ends)])
g <- function(i, end) i[match(i, ul[seq_len(end)], 0L) == 0L]
## Connected keys without duplicates
res[["key_con"]] <- Map(g, i = res[["key_con"]], end = ends)
res <- res[lengths(res[["key_con"]]) > 0L, ]
row.names(res) <- NULL
res
}
key_connect(df, key = "x", val = "y")
key key_con
1 1 1, 3, 4, 7
2 2 2, 5, 8, 9
3 10 10
4 11 11, 12
另一个不是很漂亮的解决方案,但它是基于 data.table 的。也许有帮助。
library(data.table)
library(stringr)
df = data.table(x = c(1, 1, 2, 2, 2, 2, 3, 4, 5, 1, 2,3, 4, 7, 8, 9, 4, 10, 10, 11, 12), y = c('a', 'b', 'c','d', 'e', 'f', 'a', 'a', 'e', 'k', 'l', 'm', 'n', 'b', 'e', 'e', 'b', 'x', 'y', 'z', 'z' ))
df2 = df[, .(conc = str_c(x, collapse = ", ")), by=y]
df3 = merge(df, df2, by="y", all=TRUE)
df4 = unique(df3[, .(conc = unlist(strsplit(str_c(conc, collapse = ", "), ", "))), by=x][order(conc)], by="conc")
df_final = df4[, .(conc = str_c(conc, collapse = ", ")), by=x][order(x)]
输出:
x conc
1: 1 1, 3, 4, 7
2: 2 2, 5, 8, 9
3: 10 10
4: 11 11, 12