Определение порога кадра данных без удаления значений

У меня есть фрейм данных, состоящий из неуникального идентификатора (ID) и мер некоторых свойств объектов в этом ID, примерно так:

ID   Sph
 A   1.0 
 A   1.2
 A   1.1     
 B   0.5     
 B   1.8    
 C   2.2    
 C   1.1    
 D   2.1    
 D   3.0

Во-первых, я получаю количество экземпляров каждого идентификатора как X, используя table(df$ID), то есть A=3, B=2, C=2 и D=2. Затем я хотел бы применить порог в категории «Sph» после получения количества экземпляров, ограничиваясь строками, в которых значение Sph превышает пороговое значение. Например, с порогом 2.0 я бы использовал thold=df[df$Sph>2.0,]. Наконец, я хотел бы заменить столбец ID значением X, которое я вычислил, используя table выше. Например, с порогом 1,1 в столбцах «Sph» я хотел бы получить следующий результат:

ID   Sph    
 3   1.0    
 2   1.8    
 2   2.2    
 2   2.1    
 2   3.0

Другими словами, после использования table() для получения значения x, соответствующего количеству появлений идентификатора, скажем 3, я хотел бы затем присвоить это число каждому значению в этом идентификаторе Y, которое превышает некоторый порог.


person jscmenow    schedule 02.04.2015    source источник


Ответы (2)


В вашем вопросе есть некоторые несоответствия, и вы не привели воспроизводимый пример, но вот моя попытка.

Мне нравится использовать библиотеку dplyr, в этом случае мне пришлось выламывать саппли, может быть, кто-то может улучшить мой ответ.

Вот краткая версия:

library(dplyr)
#your data
x <- data.frame(ID=c(rep("A",3),rep("B",2),rep("C",2),rep("D",2)),Sph=c(1.0,1.2,1.1,0.5,1.8,2.2,1.1,2.1,3.0),stringsAsFactors = FALSE)

#lookup table
y <- summarise(group_by(x,ID), IDn=n())

#fill in original table
x$IDn <- sapply(x$ID,function(z) as.integer(y[y$ID==z,"IDn"]))

#filter for rows where Sph greater or equal to 1.1
x <- x %>% filter(Sph>=1.1)

#done
x

А вот более длинная версия с пояснительными выводами:

> library(dplyr)
> #your data
> x <- data.frame(ID=c(rep("A",3),rep("B",2),rep("C",2),rep("D",2)),Sph=c(1.0,1.2,1.1,0.5,1.8,2.2,1.1,2.1,3.0),stringsAsFactors = FALSE)
> x
  ID Sph
1  A 1.0
2  A 1.2
3  A 1.1
4  B 0.5
5  B 1.8
6  C 2.2
7  C 1.1
8  D 2.1
9  D 3.0
> 
> #lookup table
> y <- summarise(group_by(x,ID), IDn=n())
> y
Source: local data frame [4 x 2]

  ID IDn
1  A   3
2  B   2
3  C   2
4  D   2
> 
> #fill in original table
> x$IDn <- sapply(x$ID,function(z) as.integer(y[y$ID==z,"IDn"]))
> x
  ID Sph IDn
1  A 1.0   3
2  A 1.2   3
3  A 1.1   3
4  B 0.5   2
5  B 1.8   2
6  C 2.2   2
7  C 1.1   2
8  D 2.1   2
9  D 3.0   2
> 
> #filter for rows where Sph greater or equal to 1.1
> x <- x %>% filter(Sph>=1.1)
> 
> #done
> x
  ID Sph IDn
1  A 1.2   3
2  A 1.1   3
3  B 1.8   2
4  C 2.2   2
5  C 1.1   2
6  D 2.1   2
7  D 3.0   2
person variable    schedule 02.04.2015
comment
Спасибо за ответ! Похоже, вы точно поняли, что я искал, и это сработало. Мне любопытно, какие несоответствия привели к путанице в моем вопросе? - person jscmenow; 02.04.2015
comment
Конечно, если вы посмотрите на главный вопрос с меткой [r], вы увидите, что это «Как сделать отличный воспроизводимый пример R?» Я очень рекомендую эту ветку. Вы получите больше ответов, если скопировать и вставить исходные данные в терминал r. Также я помню одно несоответствие: вы упомянули фильтрацию для порога 1,1 и выше, однако в итоговой таблице есть значение 1,0. Я не могу вспомнить других в это время. - person variable; 03.04.2015

Фактически вы можете сделать это за один шаг после вычисления X и thold, как вы это сделали в своем вопросе:

X <- table(df$ID)
thold <- df[df$Sph > 1.1,]
thold$ID <- X[as.character(thold$ID)]
thold
#   ID Sph
# 2  3 1.2
# 5  2 1.8
# 6  2 2.2
# 8  2 2.1
# 9  2 3.0

Обычно вы смотрите частоту каждого значения ID в таблице X, которую вы построили.

person josliber♦    schedule 14.06.2015