2013-07-22 3 views
3

지구, 군 및 연도가있는 데이터 세트가 있습니다. 주어진 연도/연도 조합이 특정 연도에 발생하면 나는 그 조합이 매년 발생하기를 원합니다. 아래는 내가 이것을 알아 낸 두 가지 방법입니다. 첫 번째 방법은 지구, 카운티 및 연도의 조합을 만드는 함수를 사용하며 6 행의 코드 만 필요합니다. 아래의 접근법은 paste, expand.gridstrsplit의 조합을 사용하며 훨씬 복잡하고 복잡합니다.하나의 변수가 실제로 두 개의 열인 경우 expand.grid

위의 두 가지 방법보다 훨씬 효율적인 방법이 있습니다. 예를 들어, 한 줄 또는 두 줄의 코드로 지구/군/연도 조합을 달성 할 수있는 expand.grid을 사용할 수있는 방법이 있습니까?

감사합니다. 내 기능이 그 일을 할 수는 있지만,이 질문은 나를위한 배움의 기회입니다.

다음
desired.result <- read.table(text = ' 
    state district county year apples 
     AA  C  G 1980 200 
     AA  C  H 1980  NA 
     AA  C  I 1980 250 
     AA  C  J 1980  NA 
     AA  C other 1980  20 
     AA  EC  A 1980 100 
     AA  EC  B 1980  10 
     AA  EC  C 1980 150 
     AA  EC  D 1980  NA 
     AA  EC  E 1980  NA 
     AA  WC other 1980 350 
     AA  WC  R 1980 300 
     AA  WC  S 1980  30 
     AA  WC  T 1980  NA 
     AA  C  G 1999  NA 
     AA  C  H 1999 1200 
     AA  C  I 1999 120 
     AA  C  J 1999 1250 
     AA  C other 1999  NA 
     AA  EC  A 1999 1100 
     AA  EC  B 1999  NA 
     AA  EC  C 1999  NA 
     AA  EC  D 1999 110 
     AA  EC  E 1999 1150 
     AA  WC other 1999 130 
     AA  WC  R 1999 1300 
     AA  WC  S 1999  NA 
     AA  WC  T 1999 1350 
', header=TRUE, stringsAsFactors = FALSE) 

내 가장 솔직 솔루션은 지금까지있다가하는 사용

여기
df.1 <- read.table(text = ' 
    state district county year apples 
     AA   EC  A 1980  100 
     AA   EC  B 1980  10 
     AA   EC  C 1980  150 
     AA   C  G 1980  200 
     AA   C other 1980  20 
     AA   C  I 1980  250 
     AA   WC  R 1980  300 
     AA   WC  S 1980  30 
     AA   WC  other 1980  350 
     AA   EC  A 1999 1100 
     AA   EC  D 1999  110 
     AA   EC  E 1999 1150 
     AA   C  H 1999 1200 
     AA   C  I 1999  120 
     AA   C  J 1999 1250 
     AA   WC  R 1999 1300 
     AA   WC other 1999  130 
     AA   WC  T 1999 1350 
', header=TRUE, stringsAsFactors = FALSE) 

가 원하는 결과이다 : 나는 기본 R. 여기

을 예제 데이터 세트가됩니다 선호 각 연도마다 각 지구/군 조합을 나타내는 기능 :

my.unique.function <- function(year) { 
    my.unique  <- data.frame(unique(df.1[, c('state', 'district', 'county')]), year) 
    return(my.unique = my.unique) 
} 

years <- as.data.frame(unique(df.1[, 'year'])) 
my.unique.output <- apply(years, 1, function(x) {my.unique.function(x)}) 
my.unique.output2 <- do.call(rbind.data.frame, my.unique.output) 

desired.result2 <- merge(df.1, my.unique.output2, by = c('state', 'year', 'district', 'county'), all=TRUE) 

# compare output with a priori desired result 
desired.result <- desired.result[order(desired.result$state, desired.result$year, desired.result$district, desired.result$county),] 
all.equal(desired.result[,c(1,4,2,3,5)], desired.result2[,1:5]) 

여기 내 처음에는 훨씬 더 많은 c omplex 솔루션 : 여기

# find unique combinations of district and county 
my.unique  <- unique(df.1[, c('district', 'county')]) 

# paste district and county together 
my.unique$x <- apply(my.unique[ , c('district', 'county') ] , 1 , paste , collapse = "-") 

# represent each district/county combination for each year 
expand.unique  <- expand.grid(my.unique$x, year = c(1980, 1999)) 
expand.unique$Var1 <- as.character(expand.unique$Var1) 

# split combined district/county combinations into two columns 
expand.unique$Var1b <- sub('-', ' ', expand.unique$Var1) 
unique.split  <- strsplit(expand.unique$Var1b, ' ') 
unique.splits  <- matrix(unlist(unique.split), ncol=2, byrow=TRUE, dimnames = list(NULL, c("district", "county"))) 

# create template prior to merging with original data set 
state <- 'AA' 
desired.resultb <- data.frame(state, expand.unique, unique.splits) 

# merge template with original data set so missing observations are present if a county is not included for a given year 
desired.resultc <- merge(df.1, desired.resultb, by = c('state', 'year', 'district', 'county'), all=TRUE) 
desired.resultc 

# compare output with a priori desired result 
desired.result <- desired.result[order(desired.result$state, desired.result$year, desired.result$district, desired.result$county),] 
all.equal(desired.result[,c(1,4,2,3,5)], desired.resultc[,1:5]) 

답변

10
#find all (unique) state-district-county combinations 
df.2 <- unique(df.1[,c("state","district","county")]) 

#find all (unique) years 
df.3 <- unique(df.1[,"year",drop=FALSE]) 

#Cartesian product of combinations 
df.4 <- merge(df.2,df.3) 

#merge this with the original data frame, 
#leaving NA's for unmatched parts in df.4 
merge(df.1,df.4,all=TRUE) 
1

는 네 개의 라인을 필요로 expand.grid를 사용하여 솔루션입니다. 그러나 나는 Blue Magister의 대답을 선호한다.

my.template <- expand.grid(unique(paste(df.1$state, df.1$district, df.1$county, sep= ' ')), year = unique(df.1$year)) 

my.template2 <- data.frame(do.call(rbind, strsplit(as.character(my.template$Var1), ' ')), year = my.template$year) 

colnames(my.template2) <- names(df.1)[1:4] 

desired.result2 <- merge(df.1, my.template2, all=TRUE)