我有一个在线调查数据集,参与者有多次完整的尝试,我需要按行号有选择地删除几个案例。数据存储为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中,我有多次尝试用户lisa。我想保留她的最后一次尝试,因为它更完整(var2
中没有NA),但我需要根据user_id
而不是var3
删除该行。
答案 0 :(得分: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
首先通过将var1中的非NA值的数量相加到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
然后在每个组中找到具有max(得分)的行。可能有一种更简单的方法:
> 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
你没有说复制品你想做什么......
有人可能会在抽签中张贴一条单线......
答案 1 :(得分: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))