2015-01-21 6 views
0

다른 크기의 열에서 R의 데이터를 비교하고 싶습니다.여러 개의 열을 비교하는 R

이것은 내 데이터 세트입니다.

pp_value_1 pp_value_2 pp_value_3 pp_filename nn_value_1 nn_value_2 nn_value_3 nn_filename mm_value_1 mm_value_2 mm_value_3 mm_filename 
17 73 53 CC3 5 29 53 AA2 11 56 34 AA2 
129 516 34 BB5 44 217 42 BB1 36 190 39 BB1 
107 436 44 AA3 29 147 53 CC7 30 155 31 CC1 
57 244 53 BB6 21 108 53 BB2 14 77 61 BB4 
57 227 29 AA1 21 104 39 AA6 9 48 44 BB6 
80 318 47 AA2 18 89 47 CC3 37 200 44 DD3 
128 529 56 BB4 43 222 54 CC1 36 202 50 CC3 
31 127 53 CC1 7 38 53 DD4    
18 73 47 CC2 

가 나는 duplicated 기능을 사용 TRUEFALSE 결과 열을 추가 한 후 결과를 grepped했지만 작동하지 않았다. 여기 내 코드입니다 :

v=duplicated(data$pp_filename, data$filename, data$filename) 
b=cbind(data, dup=v) 
dupl=(b[grep("FALSE", b$dup),]) 

그리고 이것은 내가 (적절한 형식으로 다시) 얻기 위해 원하는 것입니다 :

나에게
pp_value_1 pp_value_2 pp_value_3 pp_filename nn_value_1 nn_value_2 nn_value_3 nn_filename mm_value_1 mm_value_2 mm_value_3 mm_filename 
17 73 53 CC3 18 89 47 CC3 11 56 34 AA2 
80 318 47 AA2 43 222 54 CC1 30 155 31 CC1 
31 127 53 CC1 5 29 53 AA2 36 202 50 CC3 
+0

는 코드 블록 (또는 일반적으로 코드 마크 다운)에 대한 편집 창 상단의'{}'버튼을 사용합니다. – Roland

+1

'FALSE'는 R에있는 논리 값 (* 아닌 * 문자열)입니다. 왜'grep'을 사용합니까? 귀하의 데이터는 클래스 문자의 매트릭스입니까? 그것은 차선책입니다. 예상 출력이 입력에 어떻게 매핑되는지 잘 모르겠습니다. 명시 적으로 (코드를 사용하지 않고 영어로) 알려주십시오. 또한이 FAQ를 읽어보십시오. http://stackoverflow.com/a/5963610/1412059 – Roland

+0

수정 해 주셔서 감사합니다. – user3635159

답변

1

더 쉽게 조작 할 수 있도록 데이터 형식에 대한 제안입니다. 내 생각 , 데이터의 더 나은 형식은 다음과 같습니다 당신이 형식을 원하는 경우

commons = Reduce(intersect, split(lDF$filename, lDF$type)) 
lDF[lDF$filename %in% commons, ]          
# type value_1 value_2 value_3 filename 
#1 mm  11  56  34  AA2 
#3 mm  30  155  31  CC1 
#7 mm  36  202  50  CC3 
#8 nn  5  29  53  AA2 
#13 nn  18  89  47  CC3 
#14 nn  43  222  54  CC1 
#16 pp  17  73  53  CC3 
#21 pp  80  318  47  AA2 
#23 pp  31  127  53  CC1 

:

spl = split.default(DF, substring(names(DF), 1, 2)) 
lDF = do.call(rbind, 
       lapply(seq_along(spl), 
        function(i) 
          setNames(cbind(names(spl)[i], 
              spl[[i]][complete.cases(spl[[i]]), ]), 
            c("type", gsub("^(.*?)_", "", names(spl[[i]])))))) 
lDF 
# type value_1 value_2 value_3 filename 
#1 mm  11  56  34  AA2 
#2 mm  36  190  39  BB1 
#3 mm  30  155  31  CC1 
#4 mm  14  77  61  BB4 
#5 mm  9  48  44  BB6 
#6 mm  37  200  44  DD3 
#7 mm  36  202  50  CC3 
#8 nn  5  29  53  AA2 
#9 nn  44  217  42  BB1 
#.... 

그런 다음에 (적어도 내가 질문에서 이해하는 것과) 진행할 수 있습니다 몇 가지 해결 방법이 있습니다. 예컨대 :

res = lDF[lDF$filename %in% commons, ] 
tmp = split(res[-1], res[[1]]) 
do.call(cbind, 
     lapply(seq_along(tmp), 
       function(i) 
        setNames(tmp[[i]], 
          paste(names(tmp)[i], names(tmp[[i]]), sep = "_")))) 

"DF"입니다 :

DF = structure(list(pp_value_1 = c(17L, 129L, 107L, 57L, 57L, 80L, 
128L, 31L, 18L), pp_value_2 = c(73L, 516L, 436L, 244L, 227L, 
318L, 529L, 127L, 73L), pp_value_3 = c(53L, 34L, 44L, 53L, 29L, 
47L, 56L, 53L, 47L), pp_filename = structure(c(9L, 5L, 3L, 6L, 
1L, 2L, 4L, 7L, 8L), .Label = c("AA1", "AA2", "AA3", "BB4", "BB5", 
"BB6", "CC1", "CC2", "CC3"), class = "factor"), nn_value_1 = c(5L, 
44L, 29L, 21L, 21L, 18L, 43L, 7L, NA), nn_value_2 = c(29L, 217L, 
147L, 108L, 104L, 89L, 222L, 38L, NA), nn_value_3 = c(53L, 42L, 
53L, 53L, 39L, 47L, 54L, 53L, NA), nn_filename = structure(c(1L, 
3L, 7L, 4L, 2L, 6L, 5L, 8L, NA), .Label = c("AA2", "AA6", "BB1", 
"BB2", "CC1", "CC3", "CC7", "DD4"), class = "factor"), mm_value_1 = c(11L, 
36L, 30L, 14L, 9L, 37L, 36L, NA, NA), mm_value_2 = c(56L, 190L, 
155L, 77L, 48L, 200L, 202L, NA, NA), mm_value_3 = c(34L, 39L, 
31L, 61L, 44L, 44L, 50L, NA, NA), mm_filename = structure(c(1L, 
2L, 5L, 3L, 4L, 7L, 6L, NA, NA), .Label = c("AA2", "BB1", "BB4", 
"BB6", "CC1", "CC3", "DD3"), class = "factor")), .Names = c("pp_value_1", 
"pp_value_2", "pp_value_3", "pp_filename", "nn_value_1", "nn_value_2", 
"nn_value_3", "nn_filename", "mm_value_1", "mm_value_2", "mm_value_3", 
"mm_filename"), class = "data.frame", row.names = c(NA, -9L)) 
+0

감사합니다. 이것은 새로운 형식의 아주 좋은 제안입니다. 이것은 내가하고 싶은 일을 정확히 수행합니다. 제 질문이 충분히 명확하지 않아서 미안합니다. 'seq_along'을 사용하는 법을 배워야합니다. 매우 유용한 함수입니다. – user3635159

2

, 간단한 첨자 작업 그렙보다 더 적절한 것 같다. 하지만 어쨌든 grep을 사용하는 구실을 찾았습니다.

b <- read.table(header = TRUE, text = " 
pp_value_1 pp_value_2 pp_value_3 pp_filename nn_value_1 nn_value_2 nn_value_3 nn_filename mm_value_1 mm_value_2 mm_value_3 mm_filename 
17 73 53 CC3 5 29 53 AA2 11 56 34 AA2 
129 516 34 BB5 44 217 42 BB1 36 190 39 BB1 
107 436 44 AA3 29 147 53 CC7 30 155 31 CC1 
57 244 53 BB6 21 108 53 BB2 14 77 61 BB4 
57 227 29 AA1 21 104 39 AA6 9 48 44 BB6 
80 318 47 AA2 18 89 47 CC3 37 200 44 DD3 
128 529 56 BB4 43 222 54 CC1 36 202 50 CC3 
31 127 53 CC1 7 38 53 DD4 18 73 47 CC2 
") 
# Any duplicated values among the "xx_filename" columns? 
filenameCols <- grep("_filename", names(b))  
v <- apply(b[,filenameCols], 1, FUN = anyDuplicated) 
# Save rows with colliding xx_filename columns 
dupl <- b[v != 0,] 
+0

답장을 보내 주셔서 감사합니다. 그래서 내가 원했던 것은 모든'filename' 칼럼들 사이에 중복을 찾는 것이 었습니다. 당신이 제안한 솔루션은 내가 원하는 바를 거의 수행합니다. AA2와 CC3이라는 이름이 3 개의 파일 이름에서 발생하지만 2 개의 파일 이름 열에 나타납니다. 또한 BB1, BB5는 실제로 세 개의'filename' 열 모두에서 발생하지 않습니다. – user3635159