2013-08-28 3 views
1

Предположим, что у меня есть два кадра данных, df1, DF2, которые выглядят как:R Нахождение недостающих строк

df1

 User  Lab  Score 
     A   1  52 
     A   2  65 
     A   3  87 
     A   5  78 
     B   2  56 
     B   4  98 
     C   6  78 

Тогда у меня есть еще один кадр данных, где я изолированный пользователь A от остальной части кадра данных.

df2

 User  Lab  Score 
     A   1   52 
     A   2   65 
     A   3   87 
     A   5   78 

Если я хочу, чтобы создать кадр данных, который будет включать в себя все строки из df2, и если пользователь не пытался в лаборатории, за их счет до 0. Так что я хотел бы:

DF3

 User  Lab  Score 
     A   1   52 
     A   2   65 
     A   3   87 
     A   4   0 
     A   5   78     
     A   6   0 
+0

откуда вы узнали, что пользователь не предпринял попыток в лаборатории? Установлено ли значение NA? – user2510479

ответ

1

Я уверен, что есть лучший способ сделать это, но вот что я могу придумать:

##Get unique lab IDs 
labs = as.data.frame(unique(df$Lab)) 
names(labs) <- "Lab" 

df3 = merge(df2, labs, all.y = TRUE) 
df3$User[is.na(df3$User)] <- "A" 
df3[is.na(df3)] <- 0 
df3 <- df3[,c(2,1,3)] 


#> df3 
# User Lab Score 
#1 A 1 52 
#2 A 2 65 
#3 A 3 87 
#4 A 4  0 
#5 A 5 78 
#6 A 6  0 
+1

+1. Я как раз собирался предложить 'full <- data.frame (User = rep (LETTERS [1: 3], each = 6), Lab = 1: 6); final <- merge (df1, full, by = c («Пользователь», «Лаборатория»), all = TRUE); final [is.na (final)] <- 0', считая, что они захотят сделать это для всех «Пользователей» в конце концов. – A5C1D2H2I1M1N2O1R2T1

+0

Или: полный <- expand.grid (Пользователь = уникальный (пользователь df1 $), Lab = unique (df1 $ Lab)) – lauratboyer

2

Почему бы не сделать это сразу с data.table?

FinalTable = data.table(User=unique(df1$User))[,list(Lab=1:6),by=User] 
setkey(FinalTable, User, Lab) 
setkey(df1, User, Lab) 
FinalTable = df1[FinalTable] 
FinalTable[is.na(Score),Score:=0L] 

Результат:

User Lab Score 
1: A 1 52 
2: A 2 65 
3: A 3 87 
4: A 4  0 
5: A 5 78 
6: A 6  0 
7: B 1  0 
8: B 2 56 
9: B 3  0 
10: B 4 98 
11: B 5  0 
12: B 6  0 
13: C 1  0 
14: C 2  0 
15: C 3  0 
16: C 4  0 
17: C 5  0 
18: C 6 78 
0
User<-c(rep('A',4),rep('B',2),'C') 
Lab<-c(1,2,3,4,5,2,6) 
Score<-c(52,65,87,78,56,98,78) 
df1<-data.frame(User,Lab,Score) 
df2<-df1[df1$User=='A',] 
## find different value of df1$Lab and df2$Lab 
s1<-unique(df1$Lab) 
s2<-unique(df2$Lab) 
## compute length 
f1<-length(s1)-length(s2) 
f2<-dim(df2)[1] 
## initiate df3 
df3<-df2 
## expand df3, setdiff means the difference of two sets 
df3[(f2+1):(f2+f1),]<-data.frame(rep('A',f1),setdiff(s1,s2),rep(0,f1)) 
0

Если вы готовы работать с матрицей (и у вас есть уникальные записи для каждого пользователя/Lab), то вы можете использовать tapply:

mat1 <- tapply(df1$Score, list(df1$Lab, df1$User), mean) 
mat1[is.na(mat1)] <- 0 
mat1 

# A B C 
# 1 52 0 0 
# 2 65 56 0 
# 3 87 0 0 
# 4 0 98 0 
# 5 78 0 0 
# 6 0 0 78 

Теперь каждый из столбцов представляет пользователя и легко извлекает статистику пользователей:

apply(mat1, 2, mean) 
apply(mat1, 2, sd) 
Смежные вопросы