행에 개인이 하나있는 R의 데이터 프레임이 있습니다. 때로는 개인이 두 줄로 나타나고 중복 된 ID를 기반으로이 줄을 조합하고 싶습니다.R의 데이터 프레임 행을 여러 열을 기준으로 조합하십시오.
각 개인은 여러 개의 ID를 가지고 있으며 ID가 두 번 나타날 때 은 반드시 동일한 열에 나타나지 않습니다. 행 (1)의 ID b
유사하게 3 행의 ID a
동일하기 때문에 2 ID c
같음, 행의 ID a
dat <- data.frame(a = c('cat', 'canine', 'feline', 'dog'),
b = c('feline', 'puppy', 'meower', 'wolf'),
c = c('kitten', 'barker', 'kitty', 'canine'),
d = c('shorthair', 'collie', '', ''),
e = c(1, 5, 3, 8))
> dat
a b c d e
1 cat feline kitten shorthair 1
2 canine puppy barker collie 5
3 feline meower kitty 3
4 dog wolf canine 8
그래서 행 1 및 3은 결합되어야한다 : 여기서
는 예시적인 데이터 프레임 행 4의 행이 결합되어야합니다.이상적인 결과는 다음과 같아야합니다.
a.1 b.1 c.1 d.1 e.1 a.2 b.3 c.2 d.2 e.2
1 cat feline kitten shorthair 1 feline meower kitty 3
2 canine puppy barker collie 5 dog wolf canine 8
(행이 빈 문자열 ID를 공유를 기반으로 합친되지 않았 음을 유의하십시오.)이 작업을 수행 할 수있는 방법에
내 생각 은 다음과 같습니다,하지만 난 '꽤 확신 잘못된 경로로 향하게되어 문제 해결에 도움이되지 않을 수 있습니다.
각 행에 행 ID를 할당 한 다음 데이터를 녹일 수 있다고 생각했습니다. 그 후, 나는 행을 통해 행을 옮길 수 있었다. ID 중 하나가 이전 행과 일치하는 행을 찾았을 때 (예 : 3 행 ID 중 하나가 1 행 ID 중 하나와 일치하는 경우), 현재 행의 행 ID의 모든 인스턴스를 이전 행 ID와 일치하도록 변경합니다 (예 : 3의 모든 행 ID가 1로 변경됨). 이 방법 두 가지 문제가 있습니다
dat$row.id <- 1:nrow(dat)
library(reshape2)
dat.melt <- melt(dat, id.vars = c('e', 'row.id'))
for (i in 2:nrow(dat.melt)) {
# This next step is just to ignore the empty values
if (grepl('^[[:space:]]*$', dat.melt$value[i])) {
next
}
earlier.instance <- dat.melt$row.id[which(dat.melt$value[1:(i-1)] == dat.melt$value[i])]
if (length(earlier.instance) > 0) {
earlier.row.id <- earlier.instance[1]
dat.melt$row.id[dat.melt$row.id == dat.melt$row.id[i]] <- earlier.row.id
}
}
:
여기 내가 사용하고 코드입니다.
- 그것은 행 3 일치 행 1의 ID,이 경우에는 5 행 일치 행 3의 다른 ID가 모두 행 3 열 5 행 ID가 1로 변경되어야한다고 할 수있다. 이것은 행을 순차적으로 처리하는 것이 중요하다는 것을 의미합니다. 이는 apply 함수가 아닌 for 루프를 사용하게합니다. 나는 이것이 매우 R 유사하지 않다는 것을 알고 있으며, 큰 데이터 프레임을 가지고 일하고있다. 매우 느리다.
- 이 코드는 아래 출력을 생성합니다.
row.id
과variable
이 동일한 행이 여러 개 있으므로 여기에 나온 출력을 얻기 위해 캐스팅하는 방법을 모르겠습니다. 여기서dcast
을 사용하면 집계 함수를 사용해야합니다.
출력 : 여기에
e row.id variable value
1 1 3 a cat
2 5 2 a canine
3 3 3 a feline
4 8 2 a dog
5 1 3 b feline
6 5 2 b puppy
7 3 3 b meower
8 8 2 b wolf
9 1 3 c kitten
10 5 2 c barker
11 3 3 c kitty
12 8 2 c canine
13 1 3 d shorthair
14 5 2 d collie
15 3 3 d
16 8 2 d
이것은 좋은 접근 방법 인 것 같습니다.나는 벡터화 된 솔루션을 찾고 있었는데, 이것이 더 빠를 것이라고 믿었지만, _The R Inferno_의 일부를 읽은 후에, 이것이 반드시 그런 것은 아니라는 것을 알게되었습니다. 나는 몇 가지 질문을한다. 1) 왜'max (grep (...)) '를 사용하는 대신에'grepl'을 사용하고 나서'max'를 사용하여 최대 인덱스를 얻었습니까? 2)'dat [i] $ MinID'라고 쓰면,'$ $ MinID [i]'라고 쓰시겠습니까? 그것들은 나를 위해 다르게 작동합니다. 나는 실제 데이터에 대한 아이디어를 적용하고 있기 때문에 정확한 코드를 시도하지 않았으므로 구문의 정확성을 말할 수는 없지만 아이디어는 견고합니다. – njc
어디 보자. 1)'x <- grepl (...'은 일치/불일치를위한 T/F의 벡터를 반환하고,'which (x % in % TRUE)'는 T/F 요소의 위치가 참임을 의미한다. 일치가 있었다면)'max'는 data.table (또는 현재 행 i에서 가장 먼 곳)의 가장 가까운 부분을 찾습니다 .2) 나는 그런 식으로 쓰려고했습니다. 내 전체 코드를 시도해보십시오. 변경 한 시점이 아니라 현재 상태 그대로 작동하지만 사용자가 직접 확인할 수 있습니다. – moman822
감사! 어떻게''grep''이 작동하는지,''grep''로 직접 인덱스를 얻는 대신에 T/F 벡터를 생성 한 후 인덱스를 가져 오는 특별한 이유가 있는지 궁금합니다. 나는 어느 쪽의 길도 좋다고 생각한다. – njc