Пропуск NA строк в столбце индекса - PullRequest
3 голосов
/ 18 февраля 2020

У меня есть фрейм данных со столбцом со значениями TRUE и NA. Я хотел бы добавить столбец индекса к df, который индексирует все строки с TRUE, но просто пропускает все строки с NA, не удаляя их. Вот так:

VarA    ID
TRUE    1
NA      NA
NA      NA
TRUE    2
TRUE    3

На данный момент я делаю это как:

i = 1:nrow(df)
df$ID <- ifelse(df$VarA == TRUE, i, NA)

, но это дает мне

VarA    ID
TRUE    1
NA      NA
NA      NA
TRUE    4
TRUE    5

, а это не то, что я хочу , Я знаю, что это должно быть очень легко с чем-то вроде na.omit, но почему-то я просто не могу понять это.

Ответы [ 8 ]

4 голосов
/ 18 февраля 2020

Использование базы R

df1$ID2[!is.na(df1$VarA)] <- seq_along(na.omit(df1$VarA))

  VarA ID ID2
1 TRUE  1   1
2   NA NA  NA
3   NA NA  NA
4 TRUE  2   2
5 TRUE  3   3
2 голосов
/ 18 февраля 2020
# example dataset
df = data.frame(VarA = c(TRUE, NA, NA, TRUE, TRUE))

# get cumulative sum based on cases where you don't have NA in VarA
df$ID = cumsum(!is.na(df$VarA))

# if you have NA in VarA use NA instead ofthe cumulative sum
df$ID = ifelse(is.na(df$VarA), df$VarA, df$ID)

df

#   VarA ID
# 1 TRUE  1
# 2   NA NA
# 3   NA NA
# 4 TRUE  2
# 5 TRUE  3

Вы можете объединить вышеперечисленное в одной команде, если вы предпочитаете, как

df$ID = ifelse(is.na(df$VarA), df$VarA, cumsum(!is.na(df$VarA)))
1 голос
/ 18 февраля 2020

Вы можете использовать индекс i, содержащий !is.na(df$VarA), который можно использовать для подстановки df и для генерации последовательности.

i <- !is.na(df$VarA)
df$ID[i] <- seq_len(sum(i))
df
#  VarA ID
#1 TRUE  1
#2   NA NA
#3   NA NA
#4 TRUE  2
#5 TRUE  3

Или используйте which для индекса:

i <- which(df$VarA)
df$ID[i] <- seq_along(i)

Данные:

df <- data.frame(VarA = c(TRUE,NA,NA,TRUE,TRUE))
1 голос
/ 18 февраля 2020

Базовый раствор R с использованием which

df$ID[which(df$VarA)]<-seq(which(df$VarA))
1 голос
/ 18 февраля 2020

data.table решение

library( data.table )
DT <- data.table::fread("
VarA
TRUE
NA
NA
TRUE
TRUE")

DT[ !is.na(VarA), ID := .I][]

или

setDT(df)[ !is.na(VarA), ID := .I][]

приводит к

#    VarA ID
# 1: TRUE  1
# 2:   NA NA
# 3:   NA NA
# 4: TRUE  2
# 5: TRUE  3
1 голос
/ 18 февраля 2020

Один вариант в base:

transform(df, ID = replace(cumsum(!is.na(VarA)), is.na(VarA), NA))

Выход:

   VarA ID
1: TRUE  1
2:   NA NA
3:   NA NA
4: TRUE  2
5: TRUE  3
1 голос
/ 18 февраля 2020

Используя tidyverse, вы можете сделать это:

library(tidyverse)

df %>% 
  group_by(VarA) %>%
  mutate(counter = row_number(ID))

Вывод:

  VarA     ID counter
  <lgl> <int>   <int>
1 TRUE      1       1
2 NA       NA      NA
3 NA       NA      NA
4 TRUE      2       2
5 TRUE      3       3

Пример данных:

df <- read.table(text = "VarA    ID
TRUE    1
           NA      NA
           NA      NA
           TRUE    2
           TRUE    3", header = TRUE,
           stringsAsFactors = FALSE)
0 голосов
/ 18 февраля 2020

Нет необходимости в цикле или итерации:

df$ID <- ifelse(df$VarA == TRUE, TRUE, NA)

Должен дать желаемый результат.

Или, может быть, я неправильно понял, и вы хотите удалить строк с NA in VarA:

df[!is.na(df$VarA), ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...