2015-03-13 65 views
2

樣品2(虛構的),例如行:如何組合R中相同數據框中的行(基於特定列下的重複值)?在DF

userid facultyid courseid schoolid 
167  265  NA  1678 
167  71111  301  NA 

假設我有幾百重複的用戶ID就像上面的例子。但是,絕大多數用戶標識具有不同的值。

我該如何將行與重複的userid結合起來,以便堅持第一行(2行)中的列值,除非第一個值是NA(在這種情況下,NA將用任何值重新填充來自第二排)?

在本質上,從上面的例子繪畫,我的理想輸出將包含:

userid facultyid courseid schoolid 
167  265  301  1678 

回答

1
# initialize a vector that will contain row numbers which should be erased 
rows.to.erase <- c() 

# loop over the rows, starting from top 
for(i in 1:(nrow(dat)-1)) { 
    if(dat$userid[i] == dat$userid[i+1]) { 
    # loop over columns to recuperate data when a NA is present 
    for(j in 2:4) { 
     if(is.na(dat[i,j])) 
     dat[i,j] <- dat[i+1,j] 
    } 
    rows.to.erase <- append(rows.to.erase, i+1) 
    } 
} 

dat.clean <- dat[-rows.to.erase,] 
dat.clean 
# userid facultyid courseid schoolid 
# 1 167  265  301  1678 
1

下面是使用ddply一種不同的方法:

# requires the plyr package 
library(plyr) 

# Your example dataframe with added lines 
schoolex <- data.frame(userid = c(167, 167, 200, 203, 203), facultyid = c(265, 71111, 200, 300, NA), 
         courseid = c(NA, 301, 302, 303, 303), schoolid = c(1678, NA, 1678, NA, 1678)) 

schoolex_duprm <- ddply(schoolex, .(userid), summarize, facultyid2 = facultyid[!is.na(facultyid)][1], 
           courseid2 = courseid[!is.na(courseid)][1], 
           schoolid2 = schoolid[!is.na(schoolid)][1]) 
+0

嗨哈里森,非常感謝您的回答!如果我有近1000列/變量,是否有更簡單的方法來複制你的函數,或者我必須爲每個變量寫出第一個()參數? – poeticpersimmon 2015-03-13 20:28:49

+0

@bergant提供了大量列的解決方案...請參閱下面的回答 – 2015-03-13 22:41:44

1

下面是一個簡單的一行plyr。我寫這一點更普遍比你問:

a <- data.frame(x=c(1,2,3,1,2,3,1,2,3),y=c(2,3,1,1,2,3,2,3,1), 
     z=c(NA,1,NA,2,NA,3,4,NA,5),zz=c(1,NA,2,NA,3,NA,4,NA,5)) 

ddply(a,~x+y,summarize,z=first(z[!is.na(z)]),zz=first(zz[!is.na(zz)])) 

具體回答了原來的問題,如果你的數據幀被命名爲,:

ddply(a,~userid,summarize,facultyid=first(facultyid[!is.na(facultyid)]), 
     courseid=first(courseid[!is.na(courseid)], 
     schoolid=first(schoolid[!is.na(schoolid)]) 
+0

嗨,彼得,非常感謝您的回答!如果我有近1000列/變量,是否有更簡單的方法來複制你的函數,或者我必須爲每個變量寫出第一個()參數? – poeticpersimmon 2015-03-13 20:26:45

4
aggregate(x = df1, by = list(df1$userid), FUN = function(x) na.omit(x)[1])[,-1] 

或使用dplyr庫:

library(dplyr) 

df1 %>% 
    group_by(userid) %>% 
    summarise_each(funs(first(na.omit(.)))) 
+0

謝謝@bergant!你能簡單地解釋一下你函數中的不同論點嗎? – poeticpersimmon 2015-03-13 23:19:12

+0

函數(FUN)中的變量x是值的列(向量)。它針對data.frame中的每個列進行調用,並且僅針對具有相同userid的值。它是一個分組操作 - 該組由「by」參數定義。 – bergant 2015-03-13 23:31:19

相關問題