2016-12-15 1 views
2

R에서 data.tables로 작업하고 있습니다. 나는 좌표 A, B, C, D와 포인트가 속한 세트를 인코딩하는 인덱스 세트를 인코딩하는 다음 data.table을 가지고있다.R : data.table은 행 세트를 비교합니다.

library(data.table) 

     A B C D set 
    1: 0 0 0 0 1 
    2: 1 0 1 0 2 
    3: 1 1 1 0 2 
    4: 0 1 0 0 2 
    5: 1 0 1 1 2 
    6: 0 1 0 0 3 
    7: 1 1 0 0 3 
    8: 0 0 1 0 4 
    9: 1 0 1 0 4 
    10: 0 1 0 1 4 
    11: 0 0 0 0 5 
    12: 1 0 0 0 5 
    13: 1 1 1 0 5 
    14: 1 1 1 1 5 

dt = setDT(structure(list(A = c(0L, 1L, 1L, 0L, 1L, 0L, 1L, 0L, 1L, 0L, 
0L, 1L, 1L, 1L), B = c(0L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 1L, 
0L, 0L, 1L, 1L), C = c(0L, 1L, 1L, 0L, 1L, 0L, 0L, 1L, 1L, 0L, 
0L, 0L, 1L, 1L), D = c(0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 
0L, 0L, 0L, 1L), set = c(1L, 2L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 
4L, 5L, 5L, 5L, 5L)), .Names = c("A", "B", "C", "D", "set"), row.names = c(NA, 
-14L), class = "data.frame")) 

각 집합의 확률.

set  mass 
1: 1 0.27809187 
2: 2 0.02614841 
3: 3 0.36890459 
4: 4 0.28975265 
5: 5 0.03710247 

wt = setDT(structure(list(set = 1:5, mass = c(0.27809187, 0.02614841, 0.36890459, 
0.28975265, 0.03710247)), .Names = c("set", "mass"), row.names = c(NA, 
-5L), class = "data.frame")) 

나는 부분 공간에 대한 투영법을 만들고 싶습니다. CD. (이 경우 일치 1,4,6,7,11,12 원래의 점을 주 1 세트 및 3뿐만 아니라 제 2 세트

unique(dt[,c("C","D", "set")]) 
> C D set 
1: 0 0 1 
2: 1 0 2 
3: 0 0 2 
4: 1 1 2 
5: 0 0 3 
6: 1 0 4 
7: 0 1 4 
8: 0 0 5 
9: 1 0 5 
10: 1 1 5 

및 식별이 부분 공간에서 동일 같은 세트, 단지 고유의 것들을 유지하고 합계 대응하는 대중을 즉이 경우 :.

> C D set 
1: 0 0 1 
2: 1 0 2 
3: 0 0 2 
4: 1 1 2 
5: 1 0 4 
6: 0 1 4 

    set  mass 
1: 1 0.6469965 % set 1 + set 3 
2: 2 0.06325088 % set 2 + set 5 
3: 4 0.36890459 

이 당신의 아이디어를 주셔서 감사합니다

답변

2

, 우리는 x * 2^((length(x) - 1):0)으로 소수에 각 세트의 이진 값을 매핑 할 수 있습니다. 서브 세트, 또한, "C"와 "D"를, 우리가 얻을 :

coords = c("C", "D") 
d = data.frame(set = dt$set, 
      val = Reduce("+", Map("*", list(dt$C, dt$D), 2^((length(coords) - 1):0)))) 
d 

을 그리고, 우리는 같은 생각 다음 그룹 동일한 세트 수

tab = table(d$val, d$set) > 0L ## `table(d) > 0` to ignore the duplicates 
gr = colSums(tab * (2^((nrow(tab) - 1):0))) 
gr 
# 1 2 3 4 5 
# 8 11 8 6 11 

## another (pre-edit) alternative with unnecessary overhead 
#gr = cutree(hclust(dist(table(d) > 0L)), h = 0) 
#gr       
#1 2 3 4 5 
#1 2 1 3 2 

및이 그룹에 따라 골재 :

rowsum(wt$mass[match(names(gr), wt$set)], gr, reorder = FALSE) 
#   [,1] 
#8 0.64699646 
#11 0.06325088 
#6 0.28975265 
+0

'list (dt $ C, dt $ D)'대신에'dt [coords]'를 사용했을 수도 있습니다 (수동으로 다시 입력하는 대신'coords'를 사용 하시겠습니까? – Frank

+0

@Frank : 처음에는'dt [, coords]'를 의미하려고했지만'with = FALSE '가 필요했습니다. 그래서'list (dt $ C, dt $ D)'와 같이갔습니다. 'dt [coords]'가 _ "i가 data.table (또는 문자 벡터) 일 때 결합 할 열은 ...이어야합니다."_ 오류 - 아마도 최신 버전이 없습니다 –

+1

오 맞아, 나는 data.frame 대 data.table 것을 잊었다; 나는 = 틀린 방법으로 말했다. Btw, 최신 CRAN 버전은'dt [, c ("C", "D")]'를 허용하지만,'dt [, coords]'는 여전히 = FALSE가 필요합니다. 뉴스에 따르면,'dt [, ..]'가 작동 할 것입니다. https://github.com/Rdatatable/data.table/blob/master/NEWS.md – Frank

2

다소 투박한 옵션을 :. 각 세트에 대한 고유 한 문자열을 확인한 다음 그것에 관한 그룹.

coords = c("C", "D") 
gDT = setorder(unique(dt[,c(coords, "set"), with=FALSE]))[, 
    .(s = paste(do.call(paste, c(.SD, .(sep="_"))), collapse=".")) 
, by=set, .SDcols = coords][, 
    g := .GRP 
, by=s][] 

# set   s g 
# 1: 1   0_0 1 
# 2: 2 0_0.1_0.1_1 2 
# 3: 3   0_0 1 
# 4: 5 0_0.1_0.1_1 2 
# 5: 4  0_1.1_0 3 

gDT[wt, on=.(set), mass := i.mass ] 
gDT[, .(set = first(set), mass = sum(mass)), by=g] 

# g set  mass 
# 1: 1 1 0.64699646 
# 2: 2 2 0.06325088 
# 3: 3 4 0.28975265 

댓글

  • 당신은 마지막 줄에 [, g := NULL][]을에 체인에 의해 g 제거 할 수 있습니다.

  • setorder은 데이터를 정렬하여 고유 한 문자열이 동일한 세트 세트에서 동일하게 나타납니다. 당신이 gDT[, .(set = first(set), mass = sum(mass)), by=g, verbose=TRUE]처럼, 마지막 줄에 verbose = TRUE를 추가하면 당신이 볼 수있는

  • 그룹화 firstsum 작업은 최적화되어 있습니다. 프랭크의 개념과 유사