Получить первый не NA элемент в строке - PullRequest
4 голосов
/ 29 октября 2019

У меня есть фрейм данных, где каждая строка должна содержать в основном значения «Нет ответа» (-1). Я хотел бы получить первое значение каждой строки, которое не -1, предпочтительно с использованием чего-то удобного для использования.

# A tibble: 3,222 x 10
   tracc1 tracc2 tracc3 tracc4 tracc5 tracc6 tracc7 tracc8 tracc9 tracc10
   <chr>  <chr>  <chr>  <chr>  <chr>  <chr>  <chr>  <chr>  <chr>  <chr>  
 1 1      -1     -1     -1     -1     -1     7      -1     -1     -1     
 2 1      -1     -1     -1     -1     -1     -1     -1     -1     -1     
 3 1      -1     -1     -1     -1     -1     -1     -1     -1     -1     
 4 1      -1     -1     -1     -1     -1     -1     -1     -1     -1     
 5 1      -1     -1     -1     -1     -1     -1     -1     -1     -1     
 6 1      -1     -1     -1     -1     -1     -1     -1     -1     -1     
 7 1      -1     -1     -1     -1     -1     -1     -1     -1     -1     
 8 1      -1     -1     -1     -1     -1     -1     -1     -1     -1     
 9 -1     -1     3      -1     -1     -1     -1     -1     -1     -1     
10 1      -1     -1     -1     -1     -1     -1     -1     -1     -1     
# ...

Я смог использовать dpylr::unite, чтобы объединить все столбцы, ноПроблемы возникают, когда одна строка имеет несколько действительных ответов. В приведенном ниже примере строка 1 должна давать 1 вместо 17.

> df %>%
    mutate_at(vars(starts_with("tracc")),
              function(t) {if_else(t < 0,"",t)}) %>%
    unite("tracc",starts_with("tracc"),sep = "", na.rm = TRUE)
# A tibble: 3,222 x 1
   tracc
   <chr>
 1 17
 2 1
 3 1
 4 1
 5 1
 6 1
 7 1
 8 1
 9 3
10 1
# ...

Ответы [ 4 ]

7 голосов
/ 29 октября 2019

Попробуйте этот простой код:

apply(df, 1, function(x) x[x != -1][1])

Параллельно применяется к каждой строке.

5 голосов
/ 29 октября 2019

Один dplyr параметр может быть:

df %>%
 mutate_all(~ replace(., . == "-1", NA_integer_)) %>%
 transmute(tracc = coalesce(!!!.))

   tracc
1      1
2      1
3      1
4      1
5      1
6      1
7      1
8      1
9      3
10     1
2 голосов
/ 29 октября 2019

Мы можем использовать векторизованную опцию с row/column индексированием

df[cbind(seq_len(nrow(df)), max.col(df != -1, 'first'))]
2 голосов
/ 29 октября 2019

Еще один способ сделать это с dplyr

library(dplyr)
df %>% mutate(row_num = row_number()) %>% # add column with row number
       pivot_longer(-row_num,names_to='tracc') %>% # pivot to get three columns
       mutate(tracc=as.numeric(str_replace(tracc,'tracc',''))) %>% # convert tracc to numeric
       filter(value != -1) %>% # keep only -1 values
       arrange(tracc) %>% # sort by tracc
       group_by(row_num)  %>% 
       filter(row_number()==1) # keep first -1 value by row_num
# A tibble: 10 x 3
# Groups:   row_num [10]
#   row_num tracc value
#     <int> <dbl> <int>
# 1       1     1     1
# 2       2     1     1
# 3       3     1     1
# 4       4     1     1
# 5       5     1     1
# 6       6     1     1
# 7       7     1     1
# 8       8     1     1
# 9      10     1     1
#10       9     3     3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...