我确实有一个统计例程,它不喜欢行精确重复(没有ID)导致空距离。
所以我首先检测我删除的重复项,应用我的例程并将剩下的记录合并。
为简单起见,请考虑使用rownames
作为ID /密钥。
我找到了以下方式在基础R中实现我的结果:
data <- data.frame(x=c(1,1,1,2,2,3),y=c(1,1,1,4,4,3))
# check duplicates and get their ID -- cf. https://stackoverflow.com/questions/12495345/find-indices-of-duplicated-rows
dup1 <- duplicated(data)
dupID <- rownames(data)[dup1 | duplicated(data[nrow(data):1, ])[nrow(data):1]]
# keep only those records that do have duplicates to preveng running folowing steps on all rows
datadup <- data[dupID,]
# "hash" row
rowhash <- apply(datadup, 1, paste, collapse="_")
idmaps <- split(rownames(datadup),rowhash)
idmaptable <- do.call("rbind",lapply(idmaps,function(vec)data.frame(mappedid=vec[1],otherids=vec[-1],stringsAsFactors = FALSE)))
这给了我想要的东西,即重复数据删除数据(简单)和映射表。
> (data <- data[!dup1,])
x y
1 1 1
4 2 4
6 3 3
> idmaptable
mappedid otherids
1_1.1 1 2
1_1.2 1 3
2_4 4 5
我想知道是否有更简单或更有效的方法(data.table
/ dplyr
已被接受)。建议的其他选择吗?
答案 0 :(得分:4)
使用data.table ...
library(data.table)
setDT(data)
# tag groups of dupes
data[, g := .GRP, by=x:y]
# do whatever analysis
f = function(DT) Reduce(`+`, DT)
resDT = unique(data, by="g")[, res := f(.SD), .SDcols = x:y][]
# "update join" the results back to the main table if needed
data[resDT, on=.(g), res := i.res ]
OP跳过了示例的中心部分(使用重复数据删除的数据),所以我只是编造了f
。
答案 1 :(得分:1)
使用tidyverse
的解决方案。我通常不会在行名称中存储信息,因此我创建了ID
和ID2
来存储信息。但是,当然,您可以根据自己的需要进行更改。
library(tidyverse)
idmaptable <- data %>%
rowid_to_column() %>%
group_by(x, y) %>%
filter(n() > 1) %>%
unite(ID, x, y) %>%
mutate(ID2 = 1:n()) %>%
group_by(ID) %>%
mutate(ID_type = ifelse(row_number() == 1, "mappedid", "otherids")) %>%
spread(ID_type, rowid) %>%
fill(mappedid) %>%
drop_na(otherids) %>%
mutate(ID2 = 1:n())
idmaptable
# A tibble: 3 x 4
# Groups: ID [2]
ID ID2 mappedid otherids
<chr> <int> <int> <int>
1 1_1 1 1 2
2 1_1 2 1 3
3 2_4 1 4 5
答案 2 :(得分:1)
对基础R解决方案进行了一些改进,
select *
, case when value1>=65 and min(value2) over (partition by site_id, sector_id)<25 then 'LOW_LOAD_CELL' end cell_status
from your_table
由此给出,
df <- data[duplicated(data)|duplicated(data, fromLast = TRUE),] do.call(rbind, lapply(split(rownames(df), do.call(paste, c(df, sep = '_'))), function(i) data.frame(mapped = i[1], others = i[-1], stringsAsFactors = FALSE)))
当然,
mapped others 1_1.1 1 2 1_1.2 1 3 2_4 4 5