Как объединить 2 строковых столбца в одном кадре данных? - PullRequest
1 голос
/ 13 марта 2020

У меня есть набор данных с 2 столбцами имен генов, которые выглядят так:

Gene_names1    Gene_names2
ACE                 .
BRCA                .
.                   SEP7
.                   CTFL
HER2                .
ZAP70               .

Есть ли способ объединить эти столбцы в одном наборе данных, чтобы получить вывод:

Gene_names1    Gene_names2     Gene_names3
ACE                 .              ACE
BRCA                .              BRCA
.                   CTFL           CTFL
.                   CTFL           CTFL 
HER2                .              HER2              
ZAP70               .              ZAP70

Я пытался ответить на этот вопрос, используя похожие вопросы, но большинство из них имеют данные о цифрах c, и я получаю ошибки, требующие значений чисел c - есть ли способ сделать это со строками?

Например, я пытался:

df$Gene_names3 <- coalesce(df$Gene_names1, df$Gene_names2) #runs but is a replicate of Gene_names1

df$Gene_names3<-rowSums(df[, c("Gene_names1", "Gene_names2")], na.rm=T) #numeric error

df %>% mutate(Category = coalesce(Gene_names1, Gene_names2))

Ошибка: имена столбцов X, Y, Z, Z1 не должны дублироваться. Используйте .name_repair для определения исправления.

Я вижу, что что-то вроде df[, Gene_names3 := Gene_names1][is.na(Gene_names1), Gene_names3 := Gene_names2][] может работать, но я не знаю, как изменить is.na() на "is". если это имеет смысл.

У меня всего 230 столбцов, Gene_names1 - это фактически номер столбца 210, а Gene_names2 - это столбец 222 для контекста.

structure(list(Gene_names1 = c("ACE", "BRCA", ".", ".", "HER2", 
"ZAP70"), Gene_names2 = c(".", ".", "SEP7", "CTFL", ".", "."
)), row.names = c(NA, -6L), class = c("data.table", "data.frame"
))

Ответы [ 4 ]

0 голосов
/ 13 марта 2020

Используйте unite в tidyr, чтобы вставить несколько столбцов в один.

library(dplyr)
library(tidyr)

df %>%
  mutate_all(na_if, ".") %>% 
  unite("Gene_names3", sep = "", remove = F, na.rm = T)

  Gene_names3 Gene_names1 Gene_names2
1         ACE         ACE        <NA>
2        BRCA        BRCA        <NA>
3        SEP7        <NA>        SEP7
4        CTFL        <NA>        CTFL
5        HER2        HER2        <NA>
6       ZAP70       ZAP70        <NA>

или

df %>%
  unite("Gene_names3", sep = "", remove = F) %>%
  mutate(Gene_names3 = sub("[.]", "", Gene_names3))
0 голосов
/ 13 марта 2020

Использование fcoalesce

df[] <- lapply(df, function(x) replace(x, x==".", NA))
df$Gene_names3 <- data.table::fcoalesce(df)
df

   Gene_names1 Gene_names2 Gene_names3
1:         ACE        <NA>         ACE
2:        BRCA        <NA>        BRCA
3:        <NA>        SEP7        SEP7
4:        <NA>        CTFL        CTFL
5:        HER2        <NA>        HER2
6:       ZAP70        <NA>       ZAP70
0 голосов
/ 13 марта 2020

Просто выберите non- "." в каждой строке, используя apply.

dat$Gene_names3 <- apply(dat, 1, function(x) x[!x == "."])
dat
#    Gene_names1 Gene_names2 Gene_names3
# 1:         ACE           .         ACE
# 2:        BRCA           .        BRCA
# 3:           .        SEP7        SEP7
# 4:           .        CTFL        CTFL
# 5:        HER2           .        HER2
# 6:       ZAP70           .       ZAP70
0 голосов
/ 13 марта 2020

Вы можете просто unlist, отфильтровать . и прикрепить к своему df, то есть

 df$new <- unlist(df)[unlist(df) != '.']

#   Gene_names1 Gene_names2   new
#1:         ACE           .   ACE
#2:        BRCA           .  BRCA
#3:           .        SEP7  HER2
#4:           .        CTFL ZAP70
#5:        HER2           .  SEP7
#6:       ZAP70           .  CTFL
...