Замените NA другим значением строки на основе идентификатора

Я хотел бы заменить NA значением из других строк на основе идентификатора. Я нашел похожие вопросы, но не нашел решения своей проблемы.

Нижняя часть таблицы

   XCODE Age Sex ResultA ResultB ResultC
1   X001  12   2       2       3       4
2   X002  23   2       4       6      66
3   X003  NA  NA      NA      NA      NA
4   X004  32   1       1       7       3
5   X005  NA  NA      NA      NA      NA
6   X001  NA  NA      NA      NA      NA
7   X002  NA  NA      NA      NA      NA
8   X003  33   1       8       7       6
9   X004  NA  NA      NA      NA      NA
10  X005  55   2       8       8       8

У меня есть файл SPSS с более чем 6000 столбцов.

я использовал

library(data.table)
setDT(dataset)[, Age:= Age[!is.na(Age)][1L] , by = XCODE]

но это хорошо только для одного столбца, и мне нужно иметь дело со многими столбцами.

Итак, как я могу выполнить код выше для всех столбцов?

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

user9992957 02.04.2019 12:01

Так что всегда есть ровно одно не-NA значение и одно (или больше?) NA на группу, верно?

markus 02.04.2019 12:04

Почему тег SPSS — вы тоже ищете ответ в SPSS?

eli-k 02.04.2019 15:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
96
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Используя data.table, мы можем выбрать столбцы, которые мы хотим replace

library(data.table)
setDT(df)[, (2:ncol(df)) := lapply(.SD, function(x) 
            replace(x, is.na(x), x[!is.na(x)][1])) , XCODE]

df
#    XCODE Age Sex ResultA ResultB ResultC
# 1:  X001  12   2       2       3       4
# 2:  X002  23   2       4       6      66
# 3:  X003  33   1       8       7       6
# 4:  X004  32   1       1       7       3
# 5:  X005  55   2       8       8       8
# 6:  X001  12   2       2       3       4
# 7:  X002  23   2       4       6      66
# 8:  X003  33   1       8       7       6
# 9:  X004  32   1       1       7       3
#10:  X005  55   2       8       8       8

Используя ту же логику в dplyr, мы можем заменить NAs первым не-NA значением группы для всех столбцов.

library(dplyr)

df %>%
  group_by(XCODE) %>%
  mutate_all(~replace(., is.na(.), .[!is.na(.)][1]))


#  XCODE   Age   Sex ResultA ResultB ResultC
#   <fct> <int> <int>   <int>   <int>   <int>
# 1 X001     12     2       2       3       4
# 2 X002     23     2       4       6      66
# 3 X003     33     1       8       7       6
# 4 X004     32     1       1       7       3
# 5 X005     55     2       8       8       8
# 6 X001     12     2       2       3       4
# 7 X002     23     2       4       6      66
# 8 X003     33     1       8       7       6
# 9 X004     32     1       1       7       3
#10 X005     55     2       8       8       8

Или только выбранные столбцы

cols <- c("Age", "Sex", "ResultA","ResultB")
df %>%
  group_by(XCODE) %>%
  mutate_at(vars(cols), ~ replace(., is.na(.), .[!is.na(.)][1]))

Я использовал setDT(df)[, (2:ncol(df)) := lapply(.SD, function(x) replace(x, is.na(x), x[!is.na(x)][1])) , XCODE], и он отлично работает! Но теперь я хотел бы удалить дубликаты и оставить только один из каждого примера XCODE. Есть ли такая функция, которую я мог бы использовать с data.table?

l2archer 07.04.2019 17:37

@l2archer под одним ты имеешь в виду первый из каждого XCODE ? Вы можете попробовать сделать df[!duplicated(df$XCODE), ] после описанной выше операции.

Ronak Shah 07.04.2019 18:45

Но как тогда сохранить этот результат в data.table, чтобы потом экспортировать в .xlss? Теперь я использую options(java.parameters = "-Xmx1000m") library(WriteXLS) WriteXLS("dataset",ExcelFileName = "D:/XCodeMerged50.xlsx",row‌​.names=F,col.names=T‌​)

l2archer 22.04.2019 15:30
df1 <- df[!duplicated(df$XCODE), ] и тогда вы можете xlsx::write.xlsx(x = df1, file = "your.excelfile.xlsx",sheetName = "test") или просто использовать write.csv(df1, "test.csv")
Ronak Shah 22.04.2019 15:39

Осталось решить одну вещь. Моя таблица данных основана на файле SPSS, в котором много меток для переменных. И теперь я пометил значения, например. в ячейке есть информация об уровне образования - средняя школа. И я бы предпочел получить необработанное значение (номер метки). Как изменить кодировку значений в таблице, чтобы получить необработанное, не размеченное значение?

l2archer 22.04.2019 17:39

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

Ronak Shah 22.04.2019 17:44

Мы можем сгруппировать по XCODE и использовать fill(), чтобы заполнить NA последними не-NA. В этом случае нам нужно заполнить в обоих направлениях. Также обратите внимание, что, поскольку вы заполняете все переменные, можно использовать функцию everything()

library(tidyverse)

df %>% 
 group_by(XCODE) %>% 
 fill(everything()) %>% 
 fill(everything(), .direction = 'up')

который дает,

# A tibble: 10 x 6
# Groups:   XCODE [5]
   XCODE   Age   Sex ResultA ResultB ResultC
   <fct> <int> <int>   <int>   <int>   <int>
 1 X001     12     2       2       3       4
 2 X001     12     2       2       3       4
 3 X002     23     2       4       6      66
 4 X002     23     2       4       6      66
 5 X003     33     1       8       7       6
 6 X003     33     1       8       7       6
 7 X004     32     1       1       7       3
 8 X004     32     1       1       7       3
 9 X005     55     2       8       8       8
10 X005     55     2       8       8       8

Другие вопросы по теме