Как удалить строку на основе определенного вектора в data.frame? - PullRequest
0 голосов
/ 08 января 2012

У меня есть набор данных онлайн-опроса, в котором участвуют несколько полных попыток, и мне нужно выборочно удалить несколько случаев по номеру строки.Данные хранятся в виде 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.Я хочу сохранить ее последнюю попытку, потому что она более полная (нет NA в var2), но мне нужно удалить строку на основе user_id, а не var3.

Ответы [ 2 ]

1 голос
/ 08 января 2012

Начиная с:

> 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

Затем найдите строку с 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 

Вы не сказали, что хотели делать с дубликатами ...

Кто-то, вероятно, разместит однострочник в тике ...

0 голосов
/ 09 января 2012
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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...