Объединить несколько столбцов в один и переименовать значения, основываясь на столбце, из которого он получен - PullRequest
1 голос
/ 10 марта 2020

Ввод data.frame выглядит следующим образом:

col1 col2 col3
          1
     1   
1
     1
1

Что может быть сгенерировано следующим образом: (благодаря @Sotos)

d2 <- data.frame(col1 = c('', 1, '', 1, '', 1), 
                 col2 = c('', '', 1, '', 1, ''), 
                 col3 = c(1, '', '', '', '', ''), stringsAsFactors = FALSE)

И желаемый вывод:

col1
3
2
1
2
1

Как объединить такие столбцы? Пустые ячейки просто пустые, но решение с NA может быть полезным, поскольку я могу легко заполнить их.

Ответы [ 4 ]

2 голосов
/ 10 марта 2020

Вы можете использовать apply и which, например:

apply(d2==1, 1, which)
#[1] 3 1 2 1 2 1

или если нужно с unlist

unlist(apply(d2==1, 1, which))

Используя данные, предоставленные @ Sotos.

d2 <- data.frame(col1 = c('', 1, '', 1, '', 1)
 , col2 = c('', '', 1, '', 1, '')
 , col3 = c(1, '', '', '', '', ''), stringsAsFactors = FALSE)
2 голосов
/ 10 марта 2020

Подход, использующий data.table

#library( data.table )
DT <- data.table( col1 = c(1,NA, 1, NA, 1),
                  col2 = c(NA, 1, NA, 1, NA) )
#    col1 col2
# 1:    1   NA
# 2:   NA    1
# 3:    1   NA
# 4:   NA    1
# 5:    1   NA

#update non-NA values to colnumbers
DT[, c("col1", "col2") := as.data.table( ifelse( is.na(DT), NA, col(DT) ) )]
#final output
DT[, .(col1 = fcoalesce( col1, col2 ) ) ][]
#    col1
# 1:    1
# 2:    2
# 3:    1
# 4:    2
# 5:    1   

обновление с предоставленными образцами данных

d2 <- data.frame(col1 = c('', 1, '', 1, '', 1), 
                 col2 = c('', '', 1, '', 1, ''), 
                 col3 = c(1, '', '', '', '', ''), stringsAsFactors = FALSE)

setDT(d2)
cols <- names(d2)
#update values to colunumbers
d2[, (cols) := as.data.table( ifelse( d2 == '', NA, col(d2) ) )]
#final output
d2[, .(col1 = fcoalesce( d2 ) ) ][]
#    col1
# 1:    3
# 2:    1
# 3:    2
# 4:    1
# 5:    2
# 6:    1         
1 голос
/ 10 марта 2020

Вот решение tidyverse:

df <- df %>%
  replace(is.na(.), 0) %>%
  mutate(sum = rowSums(.[1:3]))
0 голосов
/ 10 марта 2020

Векторизованная идея состоит в том, чтобы stack заменить индексом имени и обновить исходный df, то есть

d2_a <- subset(stack(d2[-1]), values == 1)
d2_a$values <- gsub('\\D+', '', d2_a$ind)
d2$col1[d2$col1 == ''] <- rev(d2_a$values)

, который дает,

      col1 col2 col3
    1    3         1
    2    1          
    3    2    1     
    4    1          
    5    2    1     
    6    1          
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...