2012-01-08 41 views
0

我有一个在线调查数据集,其中有多个参与者的完整尝试,我需要按行号有选择地删除几个案例。数据存储为data.frame。我意识到我可以手动执行此操作,但我希望将其保存为脚本,以便稍后可以使用它,或者有人可以快速高效地复制我已完成的操作。如何基于data.frame中的特定向量删除行?

我曾尝试过:我在多个位置搜索过,但我的问题似乎太简单了。我已经着眼于基于不完全的情况删除行('complete.cases'和'na.omit'),但这并不是特别想要的,因为我试图根据data.frame中的特定向量删除行

数据:

user_id var1 var2 var3 
1   NA 13 bob 
3  time 37 fred 
4  second NA lisa 
5  second 28 lisa 

因此,在上述我data.frame具有由用户丽萨多次尝试。我想保留她的最后一次尝试,因为它更完整(var2中没有NA),但我需要删除基于user_id而不是var3的行。

+0

要清楚,你想要移除除特定用户(var3)以外的所有情况,并且您想先移除那些首先缺少数据的情况? – 2012-01-08 16:59:00

+0

那么'完整性'是var1和var2中的非NAs的数量?你想保留var3中每个值的最完整的行吗?所以,尽管鲍勃和丽莎的第一次走棋一样不完整,他的入场还是留下来,因为他从来没有做过更好的事情?这是对的吗? – Spacedman 2012-01-08 16:59:55

+0

是的,我想从上面的user_id 4的数据中删除第4行。是的,实际上你们都是。我并不担心那些只有少数新来港定居人士的行,但只保留多次尝试调查的受访者的最全面尝试。 – 2012-01-08 17:01:52

回答

1

与开始:

> data 
    var1 var2 var3 user 
1 1 NA 2 bob 
2 34 3 1 bob 
3 NA NA 2 bob 
4 1 2 3 lisa 
5 1 NA 2 lisa 
6 3 4 5 joe 
7 6 NA 4 simon 

首先计算完整性得分相加非NA值的数量在VAR1到VAR3:

> data$score = apply(data[,c("var1","var2","var3")],1,function(x){sum(!is.na(x))}) 
> data 
    var1 var2 var3 user score 
1 1 NA 2 bob  2 
2 34 3 1 bob  3 
3 NA NA 2 bob  1 
4 1 2 3 lisa  3 
5 1 NA 2 lisa  2 
6 3 4 5 joe  3 
7 6 NA 4 simon  2 

然后找到最大(得分)在列每组。有可能是一个更简单的方法来做到这一点:

> pick = unlist(tapply(1:7,data$user, 
     function(x){x[data[x,"score"]==max(data[x,"score"])]})) 
> pick 
    bob joe lisa simon 
    2  6  4  7 
> data[pick,] 
    var1 var2 var3 user score 
2 34 3 1 bob  3 
6 3 4 5 joe  3 
4 1 2 3 lisa  3 
7 6 NA 4 simon  2 

如果有人有同分两排,他们会出现两次:

> data[2,'var2']=NA 
> data$score = apply(data[,c("var1","var2","var3")],1,function(x){sum(!is.na(x))}) 

现在,如果我重新计算我得到鲍勃两次:

> pick = unlist(tapply(1:7,data$user, 
    function(x){x[data[x,"score"]==max(data[x,"score"])]})) 
> pick 
bob1 bob2 joe lisa simon 
    1  2  6  4  7 

其可以通过只是在拾取计算返回第一匹配是固定的:

> pick = unlist(tapply(1:7,data$user, 
    function(x){x[data[x,"score"]==max(data[x,"score"])][1]})) 
> pick 
    bob joe lisa simon 
    1  6  4  7 

你不是说你想与重复做什么...

有人将可能有一个班轮张贴在抽动......

+0

这是有帮助的谢谢。它引导我朝着这个方向发展。我认为另一种选择是按用户和日期/时间过滤它,我应该在我的解释中加入这个选项。 – 2012-01-08 21:27:59

0
setwd("~/Stack Overflow") 
MultipleSurveys <- read.table("~/Stack Overflow/ ... 
MultipleSurveys.txt", header=T, quote="\"") 
SurvDat <- MultipleSurveys[,-ncol(MultipleSurveys)][,-1] 
NbNA <- rowSums(is.na(SurvDat)); names(NbNA) <- "NbNA" 
AMS <- cbind(MultipleSurveys,NbNA) 
minNA <- function(DT){ 
    NbSurv <- nrow(DT) 
    if (NbSurv==1) return(DT) 
    else{ 
    OldRow <- DT[1,] 
    for (r in 2:NbSurv){ 
     NewRow <- DT[r,] 
     if (NewRow$NbNA<=OldRow$NbNA) OldRow <- NewRow 
    } 
    return(OldRow) 
    } 
} 
(SingleSurveys <- by(AMS,AMS$user,minNA)) 
相关问题