2016-06-08 8 views
1

У меня есть большой набор данных, который я хочу удалить все строки, за исключением первых 8 за значение 1 переменной. (В этом примере только первый один)Удалите все, кроме первых строк из подмножества R

пример набор:

Time <- c(1:20) 
    stimulus <- c(rep("happy 1",4),rep("happy 2",4),rep("disgust 1",4),rep("anger 1",4),rep("sad 1",4)) 
    Happy <- c(runif(20,0,1)) 
    Disgust <- c(runif(20,0,1)) 
    Anger <- c(runif(20,0,1)) 
    Subj1<- data.frame(Time,stimulus,Happy,Disgust,Anger) 

SO: Я хочу, чтобы удалить все строки для SUBJ1 $ стимула 1-й строки, кроме «счастливого 1», «счастливого 2», " отвращение 1" и т.д. мне удается сделать так, чтобы Подменю новую переменную, а затем де-выбрать все, кроме первых 8 строк, используя следующий код:

Stim1<-which(Subj1$stimulus=="happy 1") 
Subj1<- Subj1[-c(Stim1[2:length(Stim1)]),] 

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

Благодарим за помощь!

+0

Вы говорите, что хотите удалить все строки «за исключением первых 8 ...», но ваш пример удаляет все, кроме первого ОДНОГО. Что вы имеете в виду? – Zelazny7

+0

Или: http://stackoverflow.com/questions/13279582/select-only-the-first-rows-for-each-unique-value-of-a-column-in-r – Jaap

ответ

1

Если нам нужно удалить первую строку на каждый «раздражитель», один вариант с data.table будет конвертировать в data.table (setDT(Subj1)), сгруппированных по «стимул», мы удалим первое наблюдение с tail

library(data.table) 
setDT(Subj1)[, tail(.SD,-1), by = stimulus] 

Или, если нам нужно только первое наблюдение, используйте head

setDT(Subj1)[, head(.SD,1), by = stimulus] 
# stimulus Time  Happy  Disgust  Anger 
#1: happy 1 1 0.2721827 0.263906233 0.3218399 
#2: happy 2 5 0.6649942 0.006288805 0.4758943 
#3: disgust 1 9 0.4102272 0.275845885 0.6631558 
#4: anger 1 13 0.2924157 0.776806617 0.8609168 
#5:  sad 1 17 0.1599896 0.010758160 0.6081846 

Или anot ее опцион unique от data.table с опцией by.

unique(setDT(Subj1), by = "stimulus") 
# Time stimulus  Happy  Disgust  Anger 
#1: 1 happy 1 0.2721827 0.263906233 0.3218399 
#2: 5 happy 2 0.6649942 0.006288805 0.4758943 
#3: 9 disgust 1 0.4102272 0.275845885 0.6631558 
#4: 13 anger 1 0.2924157 0.776806617 0.8609168 
#5: 17  sad 1 0.1599896 0.010758160 0.6081846 

dplyr вариант был бы группе «стимул» и получить первое наблюдение с slice.

library(dplyr) 
Subj1 %>% 
    group_by(stimulus) %>% 
    slice(1) 

Или используйте ave из base R

Subj1[with(Subj1, ave(seq_along(stimulus), stimulus, FUN = seq_along)==1),] 
+0

Мне нравится опция dplyr, но не спрашивает ли OP первые 8 строк? Итак, срез (8)? – BarkleyBG

+0

Да, но для примера это было 1 –

+0

@ J.Jansen Что не так с моими решениями? Я опубликовал его в первую очередь и имел базовые варианты R. – akrun

1

Вы можете использовать функцию базового R duplicated сохранить первый экземпляр уровня стимула:

newdf <- Subj1[!duplicated(Subj1$stimulus), ] 

я должен был убедитесь, что стимул не был фактором, используя струныAsFactors = F ALSE

данные

Subj1<- data.frame(Time,stimulus,Happy,Disgust,Anger, stringsAsFactors = FALSE) 

Если data.frame заказан раздражителем, и вы хотите сохранить первые м наблюдение каждого из них, вы можете использовать which с duplicated следующим образом:

# get rows to include 
myRows <- c(sapply(which(duplicated(Subj1$stimulus)), function(i) i:(i+2))) 
# subset 
newdf <- Subj1[myRows, ] 

Приведенный выше код выберет первые три наблюдения каждого уровня стимула. Обратите внимание как один из недостатков, что он не будет проверять, что на уровне стимулов достаточно наблюдений.

Однако вы можете выполнить эту проверку, используя table(Subj1$stimulus).