2016-10-12 6 views
0

다음 데이터 맹 글링 문제로 인해 문제가 있습니다. 각 데이터 집합은 aName 값 하나당 aValue의 다중 값을 갖습니다. 이것은 깔끔한 데이터 프레임에서 쉽게 나타낼 수 있습니다.키 값 쌍을 열로 펼치기

someDatasets <- list(dataset1 = data.frame(aName = c("a", "a", "a", "b", "b"), aValue = 1:5, dataset = "ds1"), 
        dataset2 = data.frame(aName = c("a", "a", "a", "b", "c", "c"), aValue = (1:6)*10 , dataset = "ds2"), 
        dataset3 = data.frame(aName = c("a", "c", "c", "c"), aValue = (1:4)*100, dataset = "ds3")) 

tidyData <- Reduce(dplyr::bind_rows, someDatasets) 

데이터 세트 변수를 개별 열로 "분산"하고 싶습니다. (I 때문에 중복 키의 원하는 출력을 생성 할 tidyr::spread을 사용할 수 없습니다.)

### 
# Desired output 
### 
# aName ds1 ds2 ds3 
# a  1 10 100 
# a  2 20 NA 
# a  3 30 NA 
# b  4 40 NA 
# b  5 NA NA 
# c  NA 50 200 
# c  NA 60 300 
# c  NA NA 400 

원하는 출력을 생성하는 깔끔한 방법이 있나요?

PS : 나는 spread-key-value-pairs-when-keys-are-in-different-columns 질문 만 집계 함수 length이 사용되기 때문에

dcast(melt(someDatasets, id = "aName", na.rm = TRUE), aName~value) 

원하는 출력을 생성하지 않는 솔루션 알고 있어요.

+0

길이가 사용되며, 그 이유는 바람직하지 않다? –

+1

%> % mutation (aName = paster (aName, 1 : n)) %> % mutate (aName = 1) aName, 1, 1))'. – lukeA

+2

"aName"및 "dataset"("tidyData"데이터 세트의 그룹)을 기준으로 보조 ID를 추가 한 다음 'dcast'를 사용하십시오. 예를 들어 보조 ID의 이름을 "ID"로 지정한 경우 'dcast (tidyDataWithID, aName + ID ~ dataset, value.var = "aValue")'를 수행 할 수 있습니다. – A5C1D2H2I1M1N2O1R2T1

답변

2

@lukeA 및 @A Handcart 및 Mohair의 의견에 명시된대로 중복 키 문제를 피하기 위해 추가 ID를 데이터에 추가 할 수 있습니다.

library(dplyr) 
library(tidyr) 

tidyData = bind_rows(someDatasets) %>% 
    group_by(dataset, aName) %>% 
    mutate(id = paste0(aName, 1:n())) %>% 
    ungroup() %>% 
    select(-aName) 

# head(tidyData) 
# Source: local data frame [6 x 3] 
# 
# aValue dataset id 
# <dbl> <chr> <chr> 
# 1  1  ds1 a1 
# 2  2  ds1 a2 
# 3  3  ds1 a3 
# 4  4  ds1 b1 
# 5  5  ds1 b2 
# 6  10  ds2 a1 

id 각 그룹 (세트) 내에서 지금은 고유 그래서 우리는 확산 진행할 수 :

tidyData %>% 
    spread(dataset, aValue) %>% 
    mutate(id = substr(id, 1, 1)) 

# Source: local data frame [10 x 4] 
# 
#  id ds1 ds2 ds3 
# <chr> <dbl> <dbl> <dbl> 
# 1  a  1 10 100 
# 2  a  2 20 NA 
# 3  a  3 30 NA 
# 4  b  4 40 NA 
# 5  b  5 NA NA 
# 6  c NA 50 200 
# 7  c NA 60 300 
# 8  c NA NA 400 
+0

감사합니다. 두 번째 출력은 고유하지 않은 'aValue' 및'tidyData %> %를 기반으로합니다. group_by (aName, dataset) %> mutate (ID = 1 : n()) %> % ungroup() %> % tidyr :: unite (col = "aName", aName, ID, sep = "#") %> % tidyr :: spread (dataset, aValue) %> % tidyr :: separate (col = "aName" (= ID), 제거 = T, sep = "#") %> % dplyr :: select (- ID)'이 작업을 수행했습니다. ''tidyr'' 버전이'reshape2'보다 더 장황한 것 같아서 불행합니다. – Drey

+0

@Drey 죄송합니다. 코드의 상단 부분을 업데이트하는 것을 잊었습니다. - 지금보십시오 (약간 덜 장황합니다 ...) – jakub

+0

'unite'를 리 설팅하고'separate'는 실제로 더 많은 readble을 만듭니다. 다시 한번 감사드립니다. – Drey

관련 문제