#r
Вопрос:
Это может быть очень простой вопрос, но я чувствую, что у меня есть два разных ответа, которые полезны, но трудно собрать воедино. Это также мой первый вопрос по StackOverflow, так что вот он:
У меня есть рамка данных, которая представляет собой измерения химического процесса. Существуют такие названия столбцов, как Воздушный клапан, клапан давления, уровень масла, уровень давления и т.д. Значения в этих столбцах являются либо NA, либо целым числом.
например:
AirValve <-c(rep(1,3),rep(2,5),rep(3,8),rep(4,4)) PressureLevel<-c(12,NA,NA,15,NA,NA,NA,NA,14,NA,NA,NA,NA,NA,NA,NA,16,NA,NA,NA) df1<-data.frame(AirValve,PressureLevel)
Я должен включить все NAs в 0, но только в определенных столбцах со словом «Уровень» в названии.
Если бы это был просто уровень давления df1$, я мог бы сделать:
df1$PressureLevel[is.na(df1$PressureLevel)] <- 0
Но есть много других столбцов с «Уровнем» в названии.
Я также знаю, что grepl можно использовать как таковой:
grepl("Level", names(df1))
но не знаю точно, что он делает или как его можно использовать вместе с предыдущей строкой.
Как бы я превратил значения NA в 0 значений только в столбцах, которые удовлетворяют этому условию grepl?
Ответ №1:
Вы ищете contains()
помощника по выбору здесь.
С помощью dplyr мы можем мутировать across()
столбцы, которые contains()
шаблон «выравнивает», и replace()
эти значения с 0.
library(dplyr)
df1 %>% mutate(across(contains("Level"), ~replace(.x, is.na(.x), 0)))
функция replace() обычно является более общей и может использоваться для замены различных значений. В частности, для NAs мы также можем использовать coalesce()
или replace_na
:
library(dplyr)
df1 %>% mutate(across(contains("Level"), ~coalesce(.x, 0)))
#OR
df1 %>% mutate(across(contains("Level"), replace_na, 0))
выход
AirValve PressureLevel
1 1 12
2 1 0
3 1 0
4 2 15
5 2 0
6 2 0
7 2 0
8 2 0
9 3 14
10 3 0
11 3 0
12 3 0
13 3 0
14 3 0
15 3 0
16 3 0
17 4 16
18 4 0
19 4 0
20 4 0
Комментарии:
1. Там также есть
replace_na
:mutate(across(contains("Level"), replace_na, 0))
2. да, вы правы, еще раз спасибо, andrew_reece, за то, что немного улучшили ответ
3. Спасибо вам за это! Если бы вместо замены NAs на 0 я хотел сделать что-то еще в тех же столбцах (например, скопировать значения из предыдущей строки), я бы просто написал что-то еще в разделе «объединение» или «замена»?
4. С
across(selection_helper)
помощью вы можете выбирать столбцы с несколькими различными критериями (сопоставление имен с «содержит», «starts_with» и т. Д., логическая индексация с «где» и т. Д.). Затем вы можете выполнить любую операцию над столбцом с.fns
аргументом across5. Пример:
df1 %>% mutate(across(contains('Level'), function(x) x 1))
добавим 1, чтобы выполнить все значения в выбранных столбцах
Ответ №2:
Мы можем использовать тот же вариант
nm1 <- grepl("Level", names(df1))
df1[nm1][is.na(df1[nm1])] <- 0
Если мы хотим заменить элементы NA на предыдущие не-NA
library(dplyr)
library(tidyr)
df1 %>%
group_by(x1) %>%
fill(x2)
Комментарии:
1. Спасибо! Если бы вместо замены NAs на 0s я хотел сделать что-то, описанное в этой ссылке , где я заменил все значения NA первым предыдущим значением, отличным от NA. Код по ссылке : df1$x2
2. @user2499554 вы можете использовать
fill
в обновлении