我需要檢查行是否部分重復,并洗掉/覆寫那些2列與存在3 個值的不同行匹配的行。一個問題是,“真實”資料框包含幾個串列列,這使得某些操作不可行。最好的情況是,如果任何可以找到匹配項的行都將獨立于列號進行檢查 - 這意味著僅保留具有非 NA 值(包括匹配列值的所有列)的列最多的行。
o1 o2 o3
1 1 NA NA
2 2 NA NA
3 3 NA NA
4 4 NA NA
5 6 NA NA
6 7 NA NA
7 5 9 NA # this row has only 2 values which match values from row 11 but the last value is na
8 10 NA NA
9 12 NA NA
10 13 NA NA
11 5 9 14 # this row has values in all 3 columns
12 14 NA NA
13 8 11 15 # so does this row
14 16 NA NA
15 17 NA NA
16 18 NA NA
17 19 NA NA
18 20 NA NA
結果應該是相同的資料幀 - 只是沒有第 7 行或第 7 行被第 11 行覆寫。
這應該很容易做到,但出于某種原因,我沒有管理它(除非以后添加更多列,否則很難概括的復雜 for 回圈)。有沒有直接的方法來做到這一點?
以上df的dput:
structure(list(o1 = c(1L, 2L, 3L, 4L, 6L, 7L, 5L, 10L, 12L, 13L,
5L, 14L, 8L, 16L, 17L, 18L, 19L, 20L), o2 = c(NA, NA, NA, NA,
NA, NA, 9L, NA, NA, NA, 9L, NA, 11L, NA, NA, NA, NA, NA), o3 = c(NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, 14L, NA, 15L, NA, NA, NA,
NA, NA)), row.names = c(NA, -18L), class = "data.frame")
如果已經有類似問題的答案,請告訴我。
uj5u.com熱心網友回復:
我想過使用dplyr:
library(dplyr)
df %>%
mutate(rn = row_number(),
count_na = rowSums(across(o1:o3, is.na))) %>%
group_by(o1, o2) %>%
slice_min(count_na) %>%
arrange(rn) %>%
ungroup() %>%
select(o1:o3)
這回傳
# A tibble: 17 x 3
o1 o2 o3
<int> <int> <int>
1 1 NA NA
2 2 NA NA
3 3 NA NA
4 4 NA NA
5 6 NA NA
6 7 NA NA
7 10 NA NA
8 12 NA NA
9 13 NA NA
10 5 9 14
11 14 NA NA
12 8 11 15
13 16 NA NA
14 17 NA NA
15 18 NA NA
16 19 NA NA
17 20 NA NA
該解決方案基于以下想法:
- 對于每一行,我們計算
NA該行中s的數量。 - 我們分組
o1并o2創建屬于一起的資料組。這是一個可能的缺陷:也許它是一種更好的方法來分組o1或進行其他分組。這取決于您的資料結構:應該1, <NA>, <NA>被1, 2, <NA>? - 分組后,我們選擇
NAs數最少的行。 - 最后我們做一些清理作業:移除輔助列、排列資料和取消分組。
uj5u.com熱心網友回復:
檢測重復項的部分解決方案,它仍然是指定要洗掉的行,時間不夠。我已經繼續“復制”了幾行。
df=read.table(text="
o1 o2 o3
1 1 NA NA
2 2 NA NA
3 3 NA NA
4 4 NA NA
5 6 NA NA
6 7 NA NA
7 5 9 NA
8 10 NA NA
9 12 NA NA
10 13 NA NA
11 5 9 14
12 14 NA NA
13 8 11 15
14 16 NA NA
15 7 1 2
16 18 NA NA
17 7 1 3
18 20 NA NA",h=T)
主要技巧是計算距離矩陣并檢查哪些行的距離為零,因為 dist 將自動估計成對距離,洗掉缺失值。
tmp=as.matrix(dist(df))
diag(tmp)=NA
tmp[lower.tri(tmp)]=NA
tod=data.frame(which(tmp==0,arr.ind=T))
導致
row col
X7 7 11
X6 6 15
X6.1 6 17
uj5u.com熱心網友回復:
這是考慮所有列的另一種方法,應該適用于任意數量的列,而不管它們的名稱或位置如何
library(dplyr)
mydf <- structure(list(o1 = c(1L, 2L, 3L, 4L, 6L, 7L, 5L, 10L, 12L, 13L,
5L, 14L, 8L, 16L, 17L, 18L, 19L, 20L),
o2 = c(NA, NA, NA, NA,
NA, NA, 9L, NA, NA, NA, 9L, NA, 11L, NA, NA, NA, NA, NA),
o3 = c(NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, 14L, NA, 15L, NA, NA, NA,
NA, NA)),
row.names = c(NA, -18L),
class = "data.frame")
columns <- names(mydf)
dummy_cols <- paste0(columns, "_dummy")
mydf %>%
# duplicate the dataframe
cbind(mydf %>% `names<-`(dummy_cols)) %>%
# arrange across all columns
arrange(across(columns)) %>%
# fill NAs downwards
tidyr::fill(dummy_cols, .direction = "down") %>%
# create a dummy ID
tidyr::unite(id_dummy, dummy_cols, sep = "") %>%
# group by the id
group_by(id_dummy) %>%
# get the first row of each
filter(row_number()==1) %>%
ungroup() %>%
select(columns)
PS也替換1 - NA - NA為1 - 2 - NA和替換1 - NA - NA為1 - NA - 3
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/338786.html
上一篇:在R中構建一個包含兩列的陣列
