2012-02-09 5 views
2

어제 내 질문에 reshaping matrices in R에 비슷한, 나는 지금 내 함수를 vectorize 수 있도록 데이터 프레임을 바꿀려고 해요. 아래 코드에서 주요 기능은 scorecard입니다. subset.loanssubset.collateral이라는 데이터 프레임이 필요합니다.목록 목록의 벡터화 R

LOANS    COLLATERAL   
id | value  id | value type    
----------  -------------------    
1  200  1  600  a 
2 4390  1  899  b    
2  860  2  190  d    
2 9750  3 4930  e    
3  600  3  300  a    
:  :  :  :  : 

을이 속으로 : 나는 모두 같이 두 개의 프레임 loanscollaterals을 바꿀 수 있는지 궁금

id | loans    collateral 
----------------------------- 
1 c(200)   data.frame(a=c(600,899), b=('a','b')) 
2 c(4390,860,9750) data.frame(a=c(190), b=c('d')) 
3 c(600)   data.frame(a=c(4930,300), b=c('e','a')) 

내 희망은 내가 그렇게한다면, 그때 수 *apply 기능 중 하나 또는 plyr 도구 상자 중 하나를 사용하여 간단히 scorecard 기능을 전체적으로 적용하십시오. 더 나은/쉬운 방법이 있다면, 그것을 언급하십시오! 나는 현재의 (a 황량한 for 루프) 사용하고 코드는 다음과 같습니다

# An Nx2 data frame of loans (ID, amount) 
loans <- read.table(...) 

# An Mx4 data frame of collaterals to loans (ID, type, value, lien) 
collateral <- read.table(...) 

# One person (ID) can have >1 loan and >1 collateral, so first just 
# find all unique IDs 
loans.ID.unique = unique(loans$ID) 

# Run an analysis on each ID grouping: 
for(n in 1:length(loans.ID.unique)) { 

    # ...all loans for that ID... 
    subset.loans  <- loans$loans[ 
         which(
          loans$scorecard_id == loans.ID.unique[n])] 

    # ...all collateral for that ID... 
    subset.collateral <- collateral[ 
         which(
          collateral$scorecard_id == loans.ID.unique[n]), 
         c('type','value','lien')] 

    # Output scores for each ID 
    scores[n,1] <- loans.ID.unique[n] 
    scores[n,c(2,3)] <- scorecard(loans=subset.loans, 
           collateral=subset.collateral, 
} 

감사합니다!

+1

당신은'plyr' 패키지에 자신을 소개한다. 1 단계 : 'merge'를 사용하여 데이터를 단일 data.frame으로 결합합니다. 2 단계 :'plyr :: ddply'를 사용하여 한 단계로 작업하십시오. – Andrie

+0

@andrie - 다운로드했지만 아직 사용하지 않았습니다. (방금 R을 한 달 전에 사용하기 시작 했으므로 살펴볼 몇 가지 사항이 있습니다.)이 말은 실제로 말한 것처럼 쉽습니다. – eykanal

+0

R 학습을 시작하면 항상 살펴볼 몇 가지 사항이 있으며 R과 함께하면 더 잘 볼 수 있습니다. 조사 할 항목 목록이 기하 급수적으로 늘어나는 것을 발견했습니다. –

답변

3

1) 데이터 구조가 없음. R에서 이러한 구조를 만드는 것은 드문 일입니다. 필요한 것을 즉시 잡아라. 여기에 LoansCollateral은 두 개의 입력 데이터 프레임이고 loanscollateral은 현재 id이 처리되는 부분입니다. 자신의 코드에 아래의 기능의 이중 해시 라인을 교체 :

ids <- union(Loans$id, Collateral$id) 
do.call("rbind", lapply(ids, function(id) { 
    loans <- Loans[Loans$id == id, "value"] 
    collateral <- Collateral[Collateral$id == id, -1] 
    c(id = id, score = sum(loans) - sum(collateral$value)) ## 
})) 

추가됨 :

2) 매트릭스. 반면에, 우리는 정말이 같이 할 수있는 이러한 구조를 만들려는 경우 :

ids <- union(Loans$id, Collateral$id) 
m <- cbind(id = ids, 
    loans = lapply(ids, function(id) Loans[Loans$id == id, "value"]), 
    collateral = lapply(ids, function(id) Collateral[Collateral$id == id, -1]) 
) 

do.call("rbind", lapply(1:nrow(m), function(i) with(m[i,], 
    c(id = id, score = sum(loans) - sum(collateral$value)) 
))) 

3) 데이터 프레임을. 우리는 교대로 데이터 프레임 d <- as.date.frame(m) 또는 거의 동일하다 다음 같은 구조를 나타낼 수있다 :

d <- data.frame(id = ids, 
    loans = I(lapply(ids, function(id) Loans[Loans$id == id, "value"])), 
    collateral = I(lapply(ids, function(id) Collateral[Collateral$id == id, -1])) 
) 
do.call("rbind", lapply(1:nrow(m), function(i) with(d, 
    c(id = id[[i]], score = sum(loans[[i]]) - sum(collateral[[i]]$value)) 
))) 

편집 : 간이 m 빌드 코드.

ADDED : 데이터 프레임 표현.

+0

매우 흥미 롭습니다. MATLAB'struct' 데이터 타입을 효과적으로 만들려고했지만 이것은 훨씬 깨끗해 보입니다. – eykanal

+0

이러한 구조를 작성하는 방법을 보여주는 예제를 추가하여 방금 어떻게 보이는지 살펴 보았습니다. –

0

데이터를 전혀 변환 할 필요가 없습니다. 실제로 data.frame 안에 data.frame을 사용할 수 없기 때문에 찾고있는 변환이 불가능합니다. 대신 스코어 카드 기능에서 lapply을 사용해보세요. 당신은 당신이 언급 한대로 데이터를 변환하고 싶다면

# Read in data 
loans=data.frame(id=c(1,2,2,2,3),value=c(200,4390,860,9750,600)) 
col=data.frame(id=c(1,1,2,3,3),value=c(600,899,190,4930,300),type=c('a','b','d','e','a')) 

# Load in scorecard function 
scorecard = function(subset.loans,subset.collateral) { 
    # Do something other than this 
    list(subset.loans,subset.collateral) 
} 

# Use lapply 
lapply(unique(loans$id), 
function (x) scorecard(loans[loans$id==x,] , col[col$id==x,c('type','value')]) 
) 

,이와 같은 뭔가를 할 수 :

loans.agg=aggregate(loans$value,by=list(loans$id),c) 
names(loans.agg)=c('id','loans') 

col.agg.val=aggregate(col$value,by=list(col$id),c) 
names(col.agg.val)=c('id','collateral') 

col.agg.type=aggregate(col$type,by=list(col$id),c) 
names(col.agg.type)=c('id','type') 

# What you probably want 
merge(merge(loans.agg,col.agg.val),col.agg.type)