2017-01-30 3 views
1

У меня есть некоторые данные о повторяющихся мерах, которые я пытаюсь очистить в R. На данный момент он находится в длинном формате, и я пытаюсь исправить некоторые записи до того, как перейду в широкий формат - например, если люди слишком много раз проводили мой опрос, я собираюсь сбросить строки. У меня есть две основные проблемы, которые я пытаюсь решить:Удалить строку из data.frame на основании условия

Изменение записи

Если кто-то взял обзор от «предтестового связи», когда он был на самом деле должен быть пост-тест, я «м фиксации его с помощью следующего кода:

data[data$UserID == 52118254, "Prepost"][2] <- 2 

Это отфильтровывает запись из этого лица на основе ID, а затем изменяет вторую запись, чтобы быть закодирован как пост-тест. Этот код имеет достаточно смысла, что его просмотр говорит мне, что происходит.

Удаление строки

Я изо всех сил, чтобы получить содержательный код для удаления лишних строк - например, если кто-то случайно нажал на мою ссылку дважды. У меня есть данные, как в следующем:

UserID Prepost Duration..in.seconds. 
1 52118250  1     357 
2 52118284  1     226 
3 52118284  1     11 #This is an extra attempt to remove 
4 52118250  2     261 
5 52118284  2     151 
#to reproduce: 
structure(list(UserID = c(52118250, 52118284, 52118284, 52118250, 52118284), Prepost = c("1", "1", "1", "2", "2"), Duration..in.seconds. = c("357", "226", "11", "261", "151")), class = "data.frame", row.names = c(NA, -5L), .Names = c("UserID", "Prepost", "Duration..in.seconds.")) 

можно фильтровать по UserID, чтобы увидеть, кто взял его слишком много раз, и я ищу способ легко удалить эти строки из набора данных. В этом случае UserID 52118284 занимает три раза, а вторая попытка должна быть удалена. Если это «читаемо», как и другое исправление, это лучше.

+0

Возможно, 'df [! Duplicated (взаимодействие (df $ UserID, df $ Prepost)),]'? –

+0

@A Я думаю, что это могло бы работать, если бы были системные проблемы, но мне нужно пройти несколько раз в каждом случае и определить, какой из них ошибочен. –

ответ

0

Спасибо @Simon за предложения. Один из критериев, который я хотел, заключался в том, что код имел смысл, когда я «читал» его.Поскольку я думал больше, еще одним критерием является то, что я хотел быть преднамеренным о том, какие изменения нужно сделать. Поэтому я включил рекомендацию Саймона в отдельный столбец, а затем воспользуюсь dplyr::filter(), чтобы исключить эти переменные. Вот что пример сегмент кода выглядел так:

#Change pre/post entries 
data[data$UserID == 52118254, "Prepost"][2] <- 2 

#Mark rows to delete 
data$toDelete <- NA #Makes new empty column for marking deletions 
data[data$UserID == 52118284,][2, "toDelete"] <- 1 #Marks row for deletion 

#Filter to exclude rows 
data %>% filter(is.na(toDelete)) 
    #Optionally add "%>% select(-toDelete)" to remove the extra column 

В моем контексте преимущество здесь, что все является преднамеренным, а не автоматическим и изменения привязаны к данным, а не числу строк, которые могут измениться. Я по-прежнему приветствую любую обратную связь или другие способы достижения этого (возможно, в один шаг).

1

Я бы воспользовался набором функций dplyr, как показано ниже. Объяснить:

group_by(UserID) поможет применять функции отдельно для каждого пользователя.
mutate(click_n = row_number()) Итеративно подсчитывает появление пользователя и сохраняет его как новую переменную click_n.

library(dplyr) 

data %>% 
    group_by(UserID) %>% 
    mutate(click_n = row_number()) 
#> Source: local data frame [5 x 4] 
#> Groups: UserID [4] 
#> 
#>  UserID Prepost Duration..in.seconds. click_n 
#>  <dbl> <chr>     <chr> <int> 
#> 1 52118254  1     357  1 
#> 2 52118284  1     226  1 
#> 3 52118284  1     11  2 
#> 4 52118250  2     261  1 
#> 5 52118280  2     151  1 

filter(click_n == 1) затем может быть использована, чтобы держать только 1-й попытки, как показано ниже.

data <- data %>% 
    group_by(UserID) %>% 
    mutate(click_n = row_number()) %>% 
    filter(click_n == 1) 
data 
#> Source: local data frame [4 x 4] 
#> Groups: UserID [4] 
#> 
#>  UserID Prepost Duration..in.seconds. click_n 
#>  <dbl> <chr>     <chr> <int> 
#> 1 52118254  1     357  1 
#> 2 52118284  1     226  1 
#> 3 52118250  2     261  1 
#> 4 52118280  2     151  1 

Обратите внимание, что этот подход предполагает, что ваш кадр данных упорядочен. I., первые щелчки появляются близко к вершине.

Если вы не знакомы с %>%, обратитесь за помощью к «оператору труб».

EXTRA:

Довести комментарий в ответ, как только вы чувствуете себя комфортно с тем, что происходит здесь, вы можете пропустить mutate линию праведный сделать следующее:

data %>% group_by(UserID) %>% filter(row_number() == 1)

+0

Спасибо. Я знаком с 'dplyr',' mutate' и 'row_number'. Это может работать из-за промежуточного шага «маркировки», какие строки удалить. Фактически я мог бы сделать переменную для этих удалений, подобно моим изменениям, а затем удалить все сразу. –

+0

Отлично. Если вы знакомы с ним, вы можете пропустить строку 'mutate' и просто перейти к' data%>% group_by (UserID)%>% filter (row_number() == 1) '. Я добавил это и для других. –

2

простое решение для удаления дубликатов ниже:

subset(data, !duplicated(data$UserID)) 

Однако, вы можете также рассмотреть Подменю по duratio n, например, если продолжительность составляет менее 30 секунд.

+0

Мне нужно сохранить дубликаты, потому что он находится в длинном формате данных прямо сейчас. Даже если я отфильтрован по повторяющимся значениям UserID и Prepost, я бы хотел больше контролировать его. EDIT: Я понял, что мои данные на примере немного неправильны, должны быть только два идентификатора, поэтому посмотрите на это снова. –

Смежные вопросы