#r #database
#r #База данных
Вопрос:
Я работаю с приведенным ниже фреймом данных, который является лишь частью полных данных, и мне нужно сжать повторяющиеся числа в столбце id в одну строку. Я хочу сохранить строку с наибольшим номером sbp, если только это не 300 или более, и в этом случае я тоже хочу отказаться от этого.
Так, например, для первых трех строк с идентификатором 13480 я хочу сохранить строку, содержащую 124, и отбросить две другие.
id,sex,visits,sbp
13480,M,2,124
13480,M,3,306
13480,M,4,116
13520,M,2,124
13520,M,3,116
13520,M,4,120
13580,M,2,NA
13580,M,3,124
Это самое дальнее, что я получил, пытался это настроить, но не уверен, что я на правильном пути:
maxsbp <- split(sbp, sbp$sbp)
r <- data.frame()
for (i in 1:length(maxsbp)){
one <- maxsbp[[i]]
index <- which(one$sbp == max(one$sbp))
select <- one[index,]
r <- rbind(r, select)
}
r1 <- r[!(sbp$sbp>=300),]
r1
Ответ №1:
Я думаю, что аккуратное решение для этого будет работать довольно хорошо. Я бы сначала отфильтровал все значения выше 300, если вы не хотите сохранять какое-либо значение выше этого порога. Затем group_by идентификатор, порядок и сохранение первого.
my.df <- data.frame("id" = c(13480,13480,13480,13520,13520,13520,13580,13580),
"sex" = c("M","M","M","M","M","M","M","M"),
"sbp"= c(124,306,116,124,116,120,NA,124))
my.df %>% filter(sbp < 300) # filter to retain only values below 300
%>% group_by(id) # group by id
%>% arrange(-sbp) # arrange by id in descending order
%>% top_n(1, sbp) # retain first value i.e. the largest
# A tibble: 3 x 3
# Groups: id [3]
# id sex sbp
# <dbl> <chr> <dbl>
#1 13480 M 124
#2 13520 M 124
#3 13580 M 124
Ответ №2:
В R очень редко вам потребуются явные for
циклы для выполнения задач.
Доступны функции, которые помогут вам выполнять такие групповые операции.
Например, в base R вы можете использовать subset
и ave
:
subset(df,sbp == ave(sbp,id,FUN = function(x) max(sbp[sbp <= 300],na.rm = TRUE)))
# id sex visits sbp
#1 13480 M 2 124
#4 13520 M 2 124
#8 13580 M 3 124
То же самое можно сделать, используя dplyr
синтаксис которого немного легче понять.
library(dplyr)
df %>%
group_by(id) %>%
filter(sbp == max(sbp[sbp <= 300], na.rm = TRUE))
Ответ №3:
slice_head
также может быть использован
my.df <- data.frame("id" = c(13480,13480,13480,13520,13520,13520,13580,13580),
"sex" = c("M","M","M","M","M","M","M","M"),
"sbp"= c(124,306,116,124,116,120,NA,124))
> my.df
id sex sbp
1 13480 M 124
2 13480 M 306
3 13480 M 116
4 13520 M 124
5 13520 M 116
6 13520 M 120
7 13580 M NA
8 13580 M 124
Действуйте просто так
my.df %>% group_by(id, sex) %>%
arrange(desc(sbp)) %>%
slice_head() %>%
filter(sbp <300)
# A tibble: 2 x 3
# Groups: id, sex [2]
id sex sbp
<dbl> <chr> <dbl>
1 13520 M 124
2 13580 M 124