подсчитать количество столбцов для каждой строки по условию на символ и пропущенное - PullRequest
0 голосов
/ 07 февраля 2020

Я хочу посчитать количество столбцов для каждой строки по условию на символ и пропущенное.

Например, у меня есть этот набор данных, test.

Я хочу создать num столбцов, считая количество столбцов «not» в пропущенном или пустом значении.

a<-c("aa","bb","cc","dd","",NA)
b<-c("",NA,"aa","","","dd")
c<-c("aa","",NA,NA,"cc","dd")
d<-c("aa","bb","",NA,"cc","dd")
test<-data.frame(cbind(a,b,c,d))

     a    b    c    d
1   aa        aa   aa
2   bb <NA>        bb
3   cc   aa <NA>     
4   dd      <NA> <NA>
5             cc   cc
6 <NA>   dd   dd   dd

Я хочу подсчитать количество столбцов, содержащих NA и пустое значение, например

     a    b    c    d   num
1   aa        aa   aa   3
2   bb <NA>        bb   2
3   cc   aa <NA>        2
4   dd      <NA> <NA>   1
5             cc   cc   2
6 <NA>   dd   dd   dd   3

Я попробовал какой-то подход в других постах, например rowSums

Подсчет количества столбцов по условию (>) для каждой строки

> test$num<-rowSums(test!=c("",NA),na.rm=T)
> test
     a    b    c    d num
1   aa        aa   aa   3
2   bb <NA>        bb   0
3   cc   aa <NA>        2
4   dd      <NA> <NA>   0
5             cc   cc   2
6 <NA>   dd   dd   dd   0

Однако, он возвращает неправильные числа, и я не смог найти причины.

Не могли бы вы дать мне знать, как решить эту проблему?

Ответы [ 4 ]

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

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

test$num <- ncol(test) - rowSums(is.na(test) | test == "")
test
#     a    b    c    d num
#1   aa        aa   aa   3
#2   bb <NA>        bb   2
#3   cc   aa <NA>        2
#4   dd      <NA> <NA>   1
#5             cc   cc   2
#6 <NA>   dd   dd   dd   3
3 голосов
/ 07 февраля 2020

Вы можете использовать nchar + rowSums

test$num <- rowSums(nchar(as.matrix(test))>1,na.rm = TRUE)

или %in% + rowSums

test$num <- rowSums(`dim<-`(!as.matrix(test) %in% c("",NA),dim(test)))

таким, что

> test
     a    b    c    d num
1   aa        aa   aa   3
2   bb <NA>        bb   2
3   cc   aa <NA>        2
4   dd      <NA> <NA>   1
5             cc   cc   2
6 <NA>   dd   dd   dd   3
3 голосов
/ 07 февраля 2020

Другая идея использования rowSums состоит в замене пустого на NA, т.е.

rowSums(!is.na(replace(test, test == '', NA)))
#[1] 3 2 2 1 2 3
2 голосов
/ 07 февраля 2020

Как насчет этого подхода из тидиверса, который также сообщает, сколько столбцов содержит NA или пустые строки?

a<-c("aa","bb","cc","dd","",NA)
b<-c("",NA,"aa","","","dd")
c<-c("aa","",NA,NA,"cc","dd")
d<-c("aa","bb","",NA,"cc","dd")
test<-data.frame(cbind(a,b,c,d))

library(magrittr) #import the pipe operator

num_cols <- test %>% 
    tibble::rowid_to_column("row_id") %>% #1st add a rowid column 
    dplyr::group_by(row_id) %>% #split the data into single row groups (i.e. 
                                #row vectors)
    tidyr::nest() %>% #turn it into a list column called data
    dplyr::mutate(num_NAs = purrr::map_dbl(data, #loop over the data column of row 
                                                  #vectors using map_dbl
                                     ~sum(is.na(.))), #count the number of NAs
                  num_empty = purrr::map_dbl(data, 
                                         #count the empty strings 
                                         ~sum(. == "", na.rm = T)),
                  num_values = purrr::map_dbl(data, 
                                          #count columns without NAs or 
                                          #missing values (what you asked for)
                                          ~length(.)-sum(num_NAs, num_empty))
            ) %>%
    dplyr::ungroup() %>% #remove the grouping structure
    dplyr::select(num_NAs, num_empty, num_values) #extract only the variables you need

test_v2 <- cbind(test, num_cols)
test_v2  

     a    b    c    d num_NAs num_empty num_values
1   aa        aa   aa       0         1          3
2   bb <NA>        bb       1         1          2
3   cc   aa <NA>            1         1          2
4   dd      <NA> <NA>       2         1          1
5             cc   cc       0         2          2
6 <NA>   dd   dd   dd       1         0          3
...