Добавить логическое значение внутри нового столбца в соответствии со значениями 'NA' - PullRequest
0 голосов
/ 12 июня 2018

Допустим, у меня есть эти данные:

name <- c("Name1","Name2","Name3","Name4",NA)
state <- c("State1","State2","State3","State4","State5")
id <- c("id1",NA,NA,"id4","id5")
size <- c(NA,"size2",NA,"size4",NA)

, а затем я создаю это df

df <- data.frame(name,state,id,size)

> df
   name  state  id  size
1 Name1 State1 id1  NA    
2 Name2 State2 NA   size2
3 Name3 State3 NA   NA    
4 Name4 State4 id4  size4
5 NA    State5 id5  NA    

И class столбцов определяется в векторе, какэто:

vars <- c("name","state","id","size")
type <- c("A","A","B","C")

class <- data.frame(vars,type)

> class
   vars type
1  name    A
2 state    A
3    id    B
4  size    C

Что я хочу сделать, это создать еще один столбец с именем type, чтобы я мог получить логическое значение вывода: если хотя бы один из этих type не является NA, он должен возвращать true внутри них, вот так:

   name  state  id  size  A     B      C
 1 Name1 State1 id1 NA    TRUE  TRUE   FALSE
 2 Name2 State2 NA  size2 TRUE  FALSE  TRUE
 3 Name3 State3 NA  NA    TRUE  FALSE  FALSE
 4 Name4 State4 id4 size4 TRUE  TRUE   TRUE
 5 NA    State5 id5 NA    TRUE  TRUE   FALSE

Как я могу работать над этим, чтобы получить что-то вроде желаемого результата?

1 Ответ

0 голосов
/ 12 июня 2018

Мы можем split столбец 'vars' по типу 'в наборе данных' class '(class - это имя функции), проходить через list, подмножество столбцов' df 'из'vars ', преобразуйте его в логический matrix, проверив, что он не равен пустому, получите rowSums и создайте логический vector, сравнив его с числом столбцов набора данных, т.е. мы проверяем числозначения TRUE равны количеству столбцов

cbind(df, sapply(split(as.character(class$vars), class$type),
             function(x) rowSums(df[x] != "") == ncol(df[x])))
#   name  state  id  size     A     B     C
#1 Name1 State1 id1        TRUE  TRUE FALSE
#2 Name2 State2     size2  TRUE FALSE  TRUE
#3 Name3 State3            TRUE FALSE FALSE
#4 Name4 State4 id4 size4  TRUE  TRUE  TRUE
#5       State5 id5       FALSE  TRUE FALSE

Другой вариант без использования split будет проходить цикл по элементам «unique» столбца «type» в «class» изатем выполните подмножество

library(tidyverse)
class %>%
    pull(type) %>%
    unique %>% 
    map(~ class %>%
              filter(type == .x) %>% 
              pull(vars) %>% 
              as.character %>% 
              select(df, .) %>%
               `!=`("") %>%
              as_tibble %>%
              reduce(`&`)) %>%
    bind_cols(df, .) 

Обновление

На основе обновленного набора данных в сообщении ОП с элементами NA мы заменим df[x] != "" на !is.na(df[x])

cbind(df, sapply(split(as.character(class$vars), class$type),
         function(x) rowSums(!is.na(df[x])) >0))
#   name  state   id  size    A     B     C
#1 Name1 State1  id1  <NA> TRUE  TRUE FALSE
#2 Name2 State2 <NA> size2 TRUE FALSE  TRUE
#3 Name3 State3 <NA>  <NA> TRUE FALSE FALSE
#4 Name4 State4  id4 size4 TRUE  TRUE  TRUE
#5  <NA> State5  id5  <NA> TRUE  TRUE FALSE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...