2011-12-16 50 views
1

我很困惑如何去做這件事。假設我在數據框中有兩列。一列是按順序(x)的數字序列,另一列是從第一個或-1(y)指定某個值。這些是匹配實驗的結果,其目標是查看是否拍攝同一個人的多張照片。在下面的例子中,有10張照片,但有6個是獨特的個人。在y列中,如果匹配則報告相應的x。對於不匹配,y是-1(也可能是NAs)。如果每個人超過2張照片,則比賽#將是最近的記錄(照片1,5和7是下面的相同人物)。該組是拍攝照片的時間段(組內沒有匹配!)。希望我有這個例子中右:比較兩列:第二列中的邏輯值是否來自列1?

x <- c(1,2,3,4,5,6,7,8,9,10) 
y <- c(-1,-1,-1,-1,1,-1,1,-1,2,4) 
group <- c(1,1,1,2,2,2,3,3,3,3) 
DF <- data.frame(x,y,group) 

我想創建一個新的變量命名獨特的個體,並有一個最終的數據集,每個單獨的單行(即只有6行,而不是10 ),也包括組信息。即如果一個人屬於所有三個羣體,則可能有「111」的值,或者如果僅在第一個和最後一個羣組中就是「101」。有小費嗎?

感謝您詢問產生的數據集。根據我給出的實際數字,我意識到我的小組解釋是不好的,所以我稍微改變了結果。獎金也會很高興,但不是關鍵。

name <- c(1,2,3,4,6,8) 
group_history <- as.character(c('111','101','100','011','010','001')) 
bonus <- as.character(c('1,5,7','2,9','3','4,10','6','8')) 
results_I_want <- data.frame(name,group_history,bonus) 

我的話,失誤較多上面固定...使用

+0

您可以添加數據集的結果將是什麼樣子的這個例子中的另一個解決方案? – 2011-12-16 21:49:24

回答

2

你給

x <- c(1,2,3,4,5,6,7,8,9,10) 
y <- c(-1,-1,-1,-1,1,-1,1,-1,3,4) 
group <- c(1,1,1,2,2,2,3,3,3,3) 

DF <- data.frame(x,y,group) 

使用xy的(更新)爲例,從創造較高的數字的映射,以降低號碼是同一個人。請注意,名稱是一個字符串,儘管它是一串數字。

bottom.df <- DF[DF$y==-1,] 
mapdown.df <- DF[DF$y!=-1,] 
mapdown <- c(mapdown.df$y, bottom.df$x) 
names(mapdown) <- c(mapdown.df$x, bottom.df$x) 

我們不知道它可能會多少次才能讓一切下降到最低人數,因此必須使用while循環。

oldx <- DF$x 
newx <- mapdown[as.character(oldx)] 
while(any(oldx != newx)) { 
    oldx = newx 
    newx = mapdown[as.character(oldx)] 
} 

結果是它所屬的組,名稱以該組的最小數量表示。

DF$id <- unname(newx) 

獲取組成員身份更困難。使用reshape2將其轉換爲寬格式(每組一列),如果該列中存在某些內容,則該列爲「1」,否則爲「0」。

library("reshape2") 

wide <- dcast(DF, id~group, value.var="id", 
       fun.aggregate=function(x){if(length(x)>0){"1"}else{"0"}}) 

最後,將這些「0」/「1」成員關係粘貼在一起以獲得您描述的分組變量。

wide$grouping = apply(wide[,-1], 1, paste, collapse="") 

結果:

> wide 
    id 1 2 3 grouping 
1 1 1 1 1  111 
2 2 1 0 0  100 
3 3 1 0 1  101 
4 4 0 1 1  011 
5 6 0 1 0  010 
6 8 0 0 1  001 

沒有 「獎金」 呢。

編輯:

獲得獎金的信息,它有助於重新映射到保留一切。如果你有很多案例,這可能會很慢。

更換oldx/newx部分有:

iterx <- matrix(DF$x, ncol=1) 
iterx <- cbind(iterx, mapdown[as.character(iterx[,1])]) 
while(any(iterx[,ncol(iterx)]!=iterx[,ncol(iterx)-1])) { 
    iterx <- cbind(iterx, mapdown[as.character(iterx[,ncol(iterx)])]) 
} 

DF$id <- iterx[,ncol(iterx)] 

要生成獎金的數據,那麼你可以使用

bonus <- tapply(iterx[,1], iterx[,ncol(iterx)], paste, collapse=",") 
wide$bonus <- bonus[as.character(wide$id)] 

其中給出:

> wide 
    id 1 2 3 grouping bonus 
1 1 1 1 1  111 1,5,7 
2 2 1 0 0  100  2 
3 3 1 0 1  101 3,9 
4 4 0 1 1  011 4,10 
5 6 0 1 0  010  6 
6 8 0 0 1  001  8 

注意這ISN」與你的示例輸出相同,但我不認爲你的示例輸出是正確的(你怎麼能有 「000」 一grouping_history?)

編輯:

現在同意。

+0

我只是修正了更多的錯誤:( – Nate 2011-12-16 22:30:03

1

獎金可變

f_bonus <- function(data=df){ 
    data_a <- subset(data,y== -1,select=x) 
    data_a$pos <- seq(nrow(data_a)) 
    data_b <- subset(df,y!= -1,select=c(x,y)) 
    data_b$pos <- match(data_b$y, data_a$x) 
    data_t <- rbind(data_a,data_b[-2]) 
    data_t <- with(data_t,tapply(x,pos,paste,sep="",collapse=",")) 
    return(data_t) 
}