У меня есть довольно большой годовой набор данных в длинном формате и с очень большим количеством пропущенных значений. Я пытаюсь извлечь точки данных для каждого столбца за последний доступный год.
Вход:
Я БЫ | Год | Икс | у |
---|---|---|---|
1 | 2017 | 1 | нет данных |
1 | 2018 | нет данных | нет данных |
1 | 2019 | 3 | нет данных |
1 | 2020 | нет данных | с |
data.frame(ID=c(1,1,1,1),
Year =c(2017, 2018, 2019, 2020),
x=c(1, NA, 3, NA),
y=c(NA, NA, NA, "c")
)
Выход:
Я БЫ | Икс | у |
---|---|---|
1 | 3 | с |
data.frame(ID=1,
x=3,
y = "c"
)
Заранее большое спасибо за вашу помощь.
Ты можешь попробовать:
library(dplyr)
library(tidyr)
dfx %>%
pivot_longer(-c(ID, Year),
values_transform = list(value = as.character)) %>%
na.omit() %>%
group_by(ID, name) %>%
filter(Year == max(Year)) %>%
dplyr::select(-Year) %>%
pivot_wider(values_from = value, names_from = name)
# # A tibble: 1 x 3
# ID x y
# <dbl> <chr> <chr>
# 1 1 3 c
Возможно, вы захотите уточнить несколько моментов в своем вопросе, чтобы получить соответствующий ответ.
Разделите логику вопроса на Репрекс. Вопрос немного неясно, как вы хотите получить результат без выбрав их вручную.
Покажите / объясните, как вы пытались решить проблему, чтобы люди не тратят впустую свое время и не думают, что вы не пробовали. От что у вас там есть, я попробую посмотреть, поможет ли вам что-нибудь.
df <- data.frame(ID=c(1,1,1,1),
Year =c(2017, 2018, 2019, 2020),
x=c(1, NA, 3, NA),
y=c(NA, NA, NA, "c")
)
# Remove year like in example?
df <- df %>%
select(., -Year) %>%
filter(, !is.na(y))
# Get values you want?
> df.x <- df %>%
select(x) %>%
na.omit() %>%
as.double()
# Put together
df[2] <- df.x
извините за неясность, это мой первый пост в stackoverflow!
Не беспокойтесь, нужно время, прежде чем будет написан хороший пост, я тоже не лучший ... пожалуйста, примите ответ, который вы предпочитаете использовать, с зеленой галочкой, которая помогает пользователям узнать ответ, который лучше всего решает заданный вопрос. :)
1) Предполагая, что строки отсортированы по году в пределах идентификатора, что имеет место в примере вопроса - если не отсортированы, то сначала отсортируйте их, используя arrange(ID, Year)
- удалите Year
, сгруппируйте по ID
, заполните каждый оставшийся столбец и возьмите последнюю строку группа.
library(dplyr, exclude = c("lag", "filter"))
library(tidyr)
DF %>%
select(-Year) %>%
group_by(ID) %>%
fill %>%
slice_tail %>%
ungroup
давая:
# A tibble: 1 x 3
ID x y
<dbl> <dbl> <chr>
1 1 3 c
2)na.locf0
из зоопарка тоже сработает и даст тот же результат.
library(dplyr, exclude = c("lag", "filter"))
library(zoo)
DF %>%
select(-Year) %>%
group_by(ID) %>%
mutate(across(.fns = na.locf0)) %>%
slice_tail %>%
ungroup
Большое спасибо, это работает отлично, но приведенное ниже решение быстрее, так как pivot_wider замедляет его (у меня около 1,5 строк)