벡터에있는 하나 이상의 객체가 다른 벡터 r dplyr에있는 하나 이상의 객체와 일치 할 때 열을 그룹화하고 색인화합니다.

다만

루프를 사용하지 않고 행을 그룹화하고 각 그룹에 인덱스를 할당하는 방법을 찾으려고합니다. 어려운 점은 그룹화 변수 num 에 고유 식별자가 없다는 것입니다. num숫자 로 구성된 벡터입니다 (문자로 정의 됨). 적어도 벡터의 숫자와 일치하는 모든 행을 그룹화하고 싶습니다. 벡터는 길이가 다르며 최대 20 개의 숫자를 포함합니다. 예를 들어 보겠습니다.

다음과 같은 데이터 프레임이 있습니다.

df <- data.frame(id = c(1:5), num = c('111;222', '333;111;444', '000;88888;1', '9999;111', '1'))

나는 구분자로 num나눈다 . 모든 행이 벡터가되도록 :

library(dplyr)
df <- df %>%
  mutate(num = str_split(num, ';'))

벡터에서 하나 이상의 숫자가 동일한 인덱스와 일치하는 모든 행을 인덱싱하고 싶습니다. 결과는 다음과 같습니다.

id     num               group_index
1  c('111','222')             1
2  c('333','111','444')       1
3  c('000','88888','1')       2
4  c('9999','444')            1
5  '1'                        2

이 예에서는 또 다른 난이도를 보여줍니다. 1 행이 그룹 1의 일부이고 num에 '444'가 포함되어 있지 않더라도 그룹 1은 '111'과 '444'로 식별됩니다 .

경우 납입은 단지 문자열이고, 나는 다음을 수행 할 것

df <- group_by(num) %>%
  mutate(group_index = group_indices(.,num))

이제 그룹을 식별하는 것부터 시작해야한다고 생각했습니다. 작동하지 않는 첫 번째 방법은 다음과 같습니다.

df <- df %>%
 group_by_if(num, any(num, str_c(num, collapse = '|')) == T)

루프를 작성하는 것으로 시작할 수 있다는 것을 알고 있습니다. 그러나 R은 루프에서 매우 효율적이지 않으므로 루프가없는 솔루션을 선호합니다. 어떤 힌트라도 도움이 될 것입니다!

페넌트

좋아,이 대답은 아마도 짧아 질 수 있지만 (아마 많이 ) igraph그룹 수를 시각적으로 검사하기 위해 모든 것을 멋지고 눈에 띄게 유지 한다고 생각합니다 .

library( data.table )
library( igraph )
#make df a data.table
setDT(df)
#split num-column to v1, v2, ... ,vn
df[, paste0("v", 1:length( tstrsplit(df$num, ";"))) := tstrsplit( num, ";")]
#    id         num   v1    v2   v3
# 1:  1     111;222  111   222 <NA>
# 2:  2 333;111;444  333   111  444
# 3:  3 000;88888;1  000 88888    1
# 4:  4    9999;111 9999   111 <NA>
# 5:  5           1    1  <NA> <NA>

#now melt to long format
df.melt <- melt(df, id.vars = "id", measure.vars = patterns("^v[0-9]"), value.name = "from" )
#create links
df.melt[, to := shift( from, type = "lead"), by = .(id)][]
#drop inomplete rows
df.melt <- df.melt[ complete.cases(df.melt), ]
#    id variable  from    to
# 1:  1       v1   111   222
# 2:  2       v1   333   111
# 3:  3       v1   000 88888
# 4:  4       v1  9999   111
# 5:  2       v2   111   444
# 6:  3       v2 88888     1

g = graph_from_data_frame( df.melt[ , .(from, to)])
# plot(g)

여기에 이미지 설명 입력

함께 작업 할 두 개의 개별 그룹이있는 것 같습니다. 어떤 노드 (번호)가 어떤 그룹에 속하는지 알아 내고이 정보를 원본 df에 사용합니다.

dt.lookup <- as.data.table( components(g)$membership, keep.rownames = TRUE )
#       V1 V2
# 1:   111  1
# 2:   333  1
# 3:   000  2
# 4:  9999  1
# 5: 88888  2
# 6:   222  1
# 7:   444  1
# 8:     1  2


#go back to the molten data of the original df
df.melt <- melt(df, id.vars = "id", measure.vars = patterns("^v[0-9]"))
df.melt <- df.melt[ complete.cases(df.melt), ]
#perform update join to get the groupnumber
df.melt[ dt.lookup, group := i.V2, on = .(value = V1) ]
#    id variable value group
# 1:  1       v1   111     1
# 2:  2       v1   333     1
# 3:  3       v1   000     2
# 4:  4       v1  9999     1
# 5:  5       v1     1     2
# 6:  1       v2   222     1
# 7:  2       v2   111     1
# 8:  3       v2 88888     2
# 9:  4       v2   111     1
# 10: 2       v3   444     1
# 11: 3       v3     1     2

#summarise to go back to oroiginal df form
df.melt[, .(num = paste0( value, collapse = ";"),
            group = paste0( unique(group), collapse = ",")),
        by = .(id) ][]

최종 출력

#    id         num group
# 1:  1     111;222     1
# 2:  2 333;111;444     1
# 3:  3 000;88888;1     2
# 4:  4    9999;111     1
# 5:  5           1     2

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관