Как вернуть несколько столбцов без учета значений Na и группировать по имени других столбцов в R? - PullRequest
0 голосов
/ 02 апреля 2019
mexico <- c(1,2,5,1,NA,1)
argentina <- c(2,2,2,2,NA,2)
italy<- c(NA,10,10,10,NA,10)
spain <- c(NA,NA,11,11,11,11)
england <- c(5,NA,10,NA,NA,12)
germany <- c(1,NA,NA,NA,NA,10)

Data_Risk = data.frame( Mexico, Argentina, Italy, Spain, England, Germany)

Data_Risk 

дает

 mexico     argentina italy spain england germany

1      1         2    NA    NA       5       1
2      2         2    10    NA      NA      NA
3      5         2    10    11      10      NA
4      1         2    10    11      NA      NA
5     NA        NA    NA    11      NA      NA
6      1         2    10    11      12      10

в этом случае мне не нужно рассматривать случаи NA, поэтому я попробовал это

Data_Risk <- as.data.table(Data_Risk)
my_c <- !apply(Data_Risk, 1, is.na)[,1]
my_L <- Data_Risk[1]
as.data.frame(my_L)[my_c]

Результаты:

  Mexico Argentina England Germany
1      1         2       5       1

в этом случае мне нужно не только то, что он рассматривает строку, но и все они.
Более того, группу по каждой строке нужно ставить в новые столбцы без учета значения, поэтому финальные таблицы должны выглядеть так:

var1           var2          var3       var4     var5    var6
mexico    argentina       england    germany     null    null
mexico    argentina         italy       null     null    null 
mexico    argentina         italy      spain  england    null
mexico    argentina         italy      spain     null    null
spain      null             null       null      null    null
mexico    argentina         italy      spain england  germany

Ответы [ 3 ]

1 голос
/ 02 апреля 2019

Существует некоторый вопрос о том, что нужно, но если вам нужно заменить каждое NA на отдельное в каждом ряду следующим не-NA, то следующее дает матрицу такой формы:

library(zoo)
t(apply(Data_Risk, 1, na.locf0, fromLast = TRUE))

давая:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    2    5    5    5    1
[2,]    2    2   10   NA   NA   NA
[3,]    5    2   10   11   10   NA
[4,]    1    2   10   11   NA   NA
[5,]   11   11   11   11   NA   NA
[6,]    1    2   10   11   12   10

или если вы хотите переместить NA в каждом ряду в конец:

t(apply(Data_Risk, 1, function(x) c(na.omit(x), rep(NA, sum(is.na(x))))))

давая:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    2    5    1   NA   NA
[2,]    2    2   10   NA   NA   NA
[3,]    5    2   10   11   10   NA
[4,]    1    2   10   11   NA   NA
[5,]   11   NA   NA   NA   NA   NA
[6,]    1    2   10   11   12   10

или эквивалентно:

t(apply(Data_Risk, 1, function(x) "length<-"(na.omit(x), length(x))))
0 голосов
/ 02 апреля 2019

Один из вариантов - посмотреть на which(!is.na(Data_Risk), arr.ind = T) и распространить его на широкую форму, заменив переменную col на order(col) и добавив столбец colnm для использования в качестве value.var в расширении додлинный (dcast) процесс.

library(data.table)
library(magrittr)

nms <- as.data.table(which(!is.na(Data_Risk), arr.ind = T))

nms[, .(colnm = names(Data_Risk)[col], col = paste0('var', order(col)))
    , by = row] %>% 
  dcast(row ~ col, value.var = 'colnm')

#    row   var1      var2    var3    var4    var5    var6
# 1:   1 mexico argentina england germany    <NA>    <NA>
# 2:   2 mexico argentina   italy    <NA>    <NA>    <NA>
# 3:   3 mexico argentina   italy   spain england    <NA>
# 4:   4 mexico argentina   italy   spain    <NA>    <NA>
# 5:   5  spain      <NA>    <NA>    <NA>    <NA>    <NA>
# 6:   6 mexico argentina   italy   spain england germany

Эквивалент dplyr код:

library(dplyr)

nms <- as.data.frame(which(!is.na(Data_Risk), arr.ind = T))

nms %>% 
  group_by(row) %>% 
  mutate(colnm = names(Data_Risk)[col],
         col = paste0('var', order(col))) %>% 
  spread(col, value = colnm) %>% 
  ungroup
0 голосов
/ 02 апреля 2019

Мы можем использовать apply по строкам, находить не-NA индексы, заменять их именами столбцов и добавлять остальные с NA.

t(apply(Data_Risk, 1, function(x) {
    inds <- which(!is.na(x))
   c(names(Data_Risk)[inds], rep(NA,ncol(Data_Risk) - length(inds)))
}))

#        [,1]         [,2]     [,3]      [,4]      [,5]      [,6]     
#[1,] "mexico" "argentina" "england" "germany" NA        NA       
#[2,] "mexico" "argentina" "italy"   NA        NA        NA       
#[3,] "mexico" "argentina" "italy"   "spain"   "england" NA       
#[4,] "mexico" "argentina" "italy"   "spain"   NA        NA       
#[5,] "spain"  NA          NA        NA        NA        NA       
#[6,] "mexico" "argentina" "italy"   "spain"   "england" "germany"

Оберните apply в data.frame(), если вы хотите, чтобы конечный результат был фреймом данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...