2 열을 기준으로 중복 행을 식별하고 표시하고 싶습니다. 각 복제본에 대해 고유 한 식별자를 만들고 싶습니다. 행이 복제본 일뿐 만 아니라 중복되는 행을 알 수 있습니다. 일부 중복 항목 쌍 (적합 및 앉음)과 중복되지 않은 다른 쌍이있는 아래와 같은 데이터 프레임이 있습니다. 항목 쌍이 복제되는 동안 포함 된 정보는 고유합니다 (예 : 한 행은 1 행에 대해 Value1에 값이 있지만 Value2 및 Value 3에는 해당하지 않지만 두 번째 또는 ‘중복’행에는 Value2 및 Value3에 대한 숫자 만 있음) 값이 아님 1)
현재 데이터 프레임
value1 value2 value3 fit sit
[1,] "1" NA NA "it1" "it2"
[2,] NA "3" "2" "it2" "it1"
[3,] "2" "3" "4" "it3" "it4"
[4,] NA NA NA "it4" "it3"
[5,] "5" NA NA "it5" "it6"
[6,] NA NA "2" "it6" "it5"
[7,] NA "4" NA "it7" "it9"
예제 데이터 프레임을 생성하는 코드
value1<-c(1,NA,2,NA,5,NA,NA)
value2<-c(NA,3,3,NA,NA,NA, 4)
value3<-c(NA,2,4,NA,NA,2, NA)
fit<-c("it1","it2","it3","it4", "it5", "it6","it7")
sit<-c("it2","it1","it4","it3", "it6", "it5", "it9")
df.now<-cbind(value1,value2,value3, fit, sit)
내가 원하는 것은 이것을 다음과 같은 데이터 프레임으로 변환하는 것입니다.
원하는 데이터 프레임
val1 val2 val3 it1 it2
[1,] "1" "3" "2" "it1" "it2"
[2,] "2" "3" "4" "it3" "it4"
[3,] "5" NA "2" "it5" "it6"
[4,] NA "4" NA "it7" "it9"
다음 단계를 수행하려고 생각했습니다. 1. 맞춤을 사용하여 새 변수를 만들고 가장 낮은 항목과 가장 높은 항목으로 앉아 중복 쌍을 식별합니다. 2. 중복 된 항목 쌍을 식별합니다. 3. ifelse를 사용하여 고유 한 정보를 선택하고 채 웁니다.
1 단계와 3 단계를 수행하는 방법을 알고 있지만 2 단계에서 멈춰 있습니다. 필요한 것은 TRUE / FALSE 중복을 식별하는 것이 아니라 각 항목 쌍에 대해 고유 식별자가있는 열을 가지고 있다고 생각합니다. 1 단계로 인해 2 개의 추가 행이 있습니다.
value1 value2 value3 fit sit lit hit dup
[1,] "1" NA NA "it1" "it2" "it1" "it2" 1
[2,] NA "3" "2" "it2" "it1" "it1" "it2" 1
[3,] "2" "3" "4" "it3" "it4" "it3" "it4" 2
[4,] NA NA NA "it4" "it3" "it3" "it4" 2
[5,] "5" NA NA "it5" "it6" "it5" "it6" 3
[6,] NA NA "2" "it6" "it5" "it5" "it6" 3
[7,] NA "4" NA "it7" "it9" "it7" "it9" NA
이 작업을 수행하는 방법을 잘 모르겠습니다.
내가 요구하는 것은 2 단계에 대한 도움이거나 아마도 내가 설명 한 단계보다 더 나은 방법으로 해결하는 것입니다.
답변
하나의 dplyr
옵션은 다음과 같습니다.
df.now %>%
group_by(pair = paste(pmax(fit, sit), pmin(fit, sit), sep = "_")) %>%
summarise_at(vars(starts_with("value")), ~ ifelse(all(is.na(.)),
NA,
first(na.omit(.))))
pair value1 value2 value3
<chr> <dbl> <dbl> <dbl>
1 it2_it1 1 3 2
2 it4_it3 2 3 4
3 it6_it5 5 NA 2
4 it9_it7 NA 4 NA
또한 개별 열에 쌍이 필요하면 추가 tidyr
하면 다음과 같이 할 수 있습니다.
df.now %>%
group_by(pair = paste(pmax(fit, sit), pmin(fit, sit), sep = "_")) %>%
summarise_at(vars(starts_with("value")), ~ ifelse(all(is.na(.)),
NA,
first(na.omit(.)))) %>%
separate(pair, into = c("fit", "hit"), sep = "_", remove = FALSE)
pair fit hit value1 value2 value3
<chr> <chr> <chr> <dbl> <dbl> <dbl>
1 it2_it1 it2 it1 1 3 2
2 it4_it3 it4 it3 2 3 4
3 it6_it5 it6 it5 5 NA 2
4 it9_it7 it9 it7 NA 4 NA
답변
ing !duplicated()
후 사용하십시오 sort
.
df.now[!duplicated(t(apply(df.now[, c("fit", "sit")], 1, sort))), ]
# value1 value2 value3 fit sit
# [1,] "1" NA NA "it1" "it2"
# [2,] "2" "3" "4" "it3" "it4"
# [3,] "5" NA NA "it5" "it6"
# [4,] NA "4" NA "it7" "it9"
답변
사용 melt/dcast
에서data.table
library(data.table)
dcast(melt(setDT(df.now)[, c('fit1', 'sit1') := .(pmin(fit, sit),
pmax(fit, sit))], measure = patterns("^value"), na.rm = TRUE),
fit1 + sit1 ~ variable, value.var = 'value')
# fit1 sit1 value1 value2 value3
#1: it1 it2 1 3 2
#2: it3 it4 2 3 4
#3: it5 it6 5 NA 2
#4: it7 it9 NA 4 NA
데이터
df.now <- data.frame(value1,value2,value3, fit, sit, stringsAsFactors = FALSE)
답변
다른 data.table
옵션 :
library(data.table)
as.data.table(df.now)[, lapply(.SD, function(x) first(x[!is.na(x)])),
.(it1=pmin(fit, sit), it2=pmax(fit, sit)),
.SDcols=value1:value3]
산출:
it1 it2 value1 value2 value3
1: it1 it2 1 3 2
2: it3 it4 2 3 4
3: it5 it6 5 <NA> 2
4: it7 it9 <NA> 4 <NA>
답변
다음은 data.table을 사용한 시도입니다. 귀하의 데이터는이라고 mydf
합니다. 먼저, 각 행을 정렬 fit
하고 sit
새 변수를 만들었습니다 group
. 그런 다음 각 그룹에 대해 세 개의 값 열 (즉, value1, value2 및 value3)에서 값을 정렬했습니다. 마지막으로 각 그룹의 첫 번째 행을 추출했습니다.
library(data.table)
mydt <- setDT(mydf)[, group := paste(sort(.SD), collapse = "_"),
.SD = c("fit", "sit"), by = 1:nrow(mydf)][,
c("value1", "value2", "value3") := lapply(.SD, sort),
.SDcols = value1:value3, by = group][, .SD[1], by = group]
mydt[]
# group value1 value2 value3 fit sit
#1: it1_it2 1 3 2 it1 it2
#2: it3_it4 2 3 4 it3 it4
#3: it5_it6 5 NA 2 it5 it6
#4: it7_it9 NA 4 NA it7 it9
데이터
mydf <- structure(list(value1 = c(1L, NA, 2L, NA, 5L, NA, NA), value2 = c(NA,
3L, 3L, NA, NA, NA, 4L), value3 = c(NA, 2L, 4L, NA, NA, 2L, NA
), fit = c("it1", "it2", "it3", "it4", "it5", "it6", "it7"),
sit = c("it2", "it1", "it4", "it3", "it6", "it5", "it9")), class = "data.frame", row.names = c(NA,
-7L))
답변
이것은 또한 사용하여 수행 할 수있는 tidyr
의 pivot_longer
와 values_drop_na = TRUE
결합 pivot_wider
:
library(tidyverse)
mydf %>%
mutate(it1 = pmin(fit, sit), it2 = pmax(fit, sit)) %>%
pivot_longer(cols = starts_with("value"), values_drop_na = TRUE) %>%
pivot_wider(id_cols = c("it1", "it2"))
#> # A tibble: 4 x 5
#> it1 it2 value1 value2 value3
#> <chr> <chr> <int> <int> <int>
#> 1 it1 it2 1 3 2
#> 2 it3 it4 2 3 4
#> 3 it5 it6 5 NA 2
#> 4 it7 it9 NA 4 NA
데이터
mydf <- structure(list(value1 = c(1L, NA, 2L, NA, 5L, NA, NA), value2 = c(NA,
3L, 3L, NA, NA, NA, 4L), value3 = c(NA, 2L, 4L, NA, NA, 2L, NA
), fit = c("it1", "it2", "it3", "it4", "it5", "it6", "it7"),
sit = c("it2", "it1", "it4", "it3", "it6", "it5", "it9")), class = "data.frame", row.names = c(NA,
-7L))