Как заменить значения в столбце data.table с помощью справочной таблицы?[Р] - PullRequest
0 голосов
/ 23 января 2019

У меня есть ключ и массивная таблица метаданных.В таблице метаданных есть столбец, содержащий следующие значения:

body_site
Lung
Lung
Brain - Amygdala
Brain - Amygdala
Brain - Caudate (basal ganglia)
Brain - Caudate (basal ganglia)
Lung
Lung
Skin - Sun Exposed (Lower leg)
Skin - Sun Exposed (Lower leg)
Brain - Spinal cord (cervical c-1)
Brain - Spinal cord (cervical c-1)

с body_site в качестве заголовка.Ключ выглядит так:

Tissue,Key
Adipose - Subcutaneous,ADPSBQ
Adipose - Visceral (Omentum),ADPVSC
Adrenal Gland,ADRNLG
Artery - Aorta,ARTAORT
Artery - Coronary,ARTACRN
Artery - Tibial,ARTTBL
Bladder,BLDDER
Brain - Amygdala,BRNAMY
Brain - Anterior cingulate cortex (BA24),BRNACC

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

Проблема в том, что, если я воспользуюсь советом очень популярного поста , который демонстрирует, как это сделать, я каким-то образом получаю таблицу, в которой only имеет значения для столбца body_site;другими словами, все другие данные в этой таблице удаляются, за исключением данных, которые были заменены.С другой стороны, замена работает, но теперь у меня есть полностью пустая таблица, за исключением заголовков.

Вот как выглядит мой код.Я включил оба решения, предложенные топ-ответчиком, оба из которых я попробовал.

library("data.table")
args = commandArgs(trailingOnly=TRUE)
# SraRunTable.txt is args[1]
#sratabl <- fread(args[1])
sratabl <- fread("SraRunTable.txt")
tiskey <- fread("GTExTissueKey.csv")
# current directory is args [2]
new <- sratabl  # create a copy of df
# using lapply, loop over columns and match values to the look up table. store in "new".
new[] <- lapply(sratabl, function(x) tiskey$Key[match(x, tiskey$Tissue)])

new <- sratabl
new[] <- tiskey$Key[match(unlist(sratabl), tiskey$Tissue)]

Ответы [ 2 ]

0 голосов
/ 23 января 2019
  1. Я думаю, что вы чрезмерно используете lapply;поскольку вы работаете с одним столбцом во фрейме, вам нет необходимости использовать его здесь.
  2. В результатах будет NA с, по крайней мере, с этими данными (и вы, вероятно, должнывсе равно остерегайтесь этого).По этой причине я предлагаю промежуточную / временную переменную.

Для вышеприведенного # 2 я буду держать переменную в кадре (а затем удалять ее) для простоты ассоциации, хотя в этом нет необходимости.для этого его так же легко можно сохранить в отдельном векторе, а затем назначить после исправления.

df1$tmp <- df2$Key[ match(df1$body_site, df2$Tissue) ]
head(df1)
#                         body_site    tmp
# 1                            Lung   <NA>
# 2                            Lung   <NA>
# 3                Brain - Amygdala BRNAMY
# 4                Brain - Amygdala BRNAMY
# 5 Brain - Caudate (basal ganglia)   <NA>
# 6 Brain - Caudate (basal ganglia)   <NA>

Это NA s, с которыми вам следует опасаться ... в следующей части используютсяновый столбец, только если нет NA.

df1$tmp <- ifelse(is.na(df1$tmp), df1$body_site, df1$tmp)
head(df1)
#                         body_site                             tmp
# 1                            Lung                            Lung
# 2                            Lung                            Lung
# 3                Brain - Amygdala                          BRNAMY
# 4                Brain - Amygdala                          BRNAMY
# 5 Brain - Caudate (basal ganglia) Brain - Caudate (basal ganglia)
# 6 Brain - Caudate (basal ganglia) Brain - Caudate (basal ganglia)

Теперь очистка:

df1$body_site <- df1$tmp
df1$tmp <- NULL

Альтернатива: объединения.

library(dplyr)
left_join(df1, df2, by=c("body_site" = "Tissue")) %>% head()
#                         body_site    Key
# 1                            Lung   <NA>
# 2                            Lung   <NA>
# 3                Brain - Amygdala BRNAMY
# 4                Brain - Amygdala BRNAMY
# 5 Brain - Caudate (basal ganglia)   <NA>
# 6 Brain - Caudate (basal ganglia)   <NA>

(такая же очисткатребуется)

library(data.table)
head( merge(df1, df2, by.x="body_site", by.y="Tissue", all.x=TRUE) )
#                             body_site    Key
# 1:                   Brain - Amygdala BRNAMY
# 2:                   Brain - Amygdala BRNAMY
# 3:    Brain - Caudate (basal ganglia)   <NA>
# 4:    Brain - Caudate (basal ganglia)   <NA>
# 5: Brain - Spinal cord (cervical c-1)   <NA>
# 6: Brain - Spinal cord (cervical c-1)   <NA>

(требуется такая же очистка)


Данные:

df1 <- read.csv(header=T, stringsAsFactors=F, text='
body_site
Lung
Lung
Brain - Amygdala
Brain - Amygdala
Brain - Caudate (basal ganglia)
Brain - Caudate (basal ganglia)
Lung
Lung
Skin - Sun Exposed (Lower leg)
Skin - Sun Exposed (Lower leg)
Brain - Spinal cord (cervical c-1)
Brain - Spinal cord (cervical c-1)')

df2 <- read.csv(header=T, stringsAsFactors=F, text='
Tissue,Key
Adipose - Subcutaneous,ADPSBQ
Adipose - Visceral (Omentum),ADPVSC
Adrenal Gland,ADRNLG
Artery - Aorta,ARTAORT
Artery - Coronary,ARTACRN
Artery - Tibial,ARTTBL
Bladder,BLDDER
Brain - Amygdala,BRNAMY
Brain - Anterior cingulate cortex (BA24),BRNACC')
0 голосов
/ 23 января 2019

Вот решение:

require(data.table)
df1 <- data.frame(a = c("a","b","c"), b = c("x","y","z"))
df2 <- data.frame(a = c("a","c"), b = c("new_x","new_z"))
setDT(df1)
setDT(df2)

# inspect each df
df1
#    a b
# 1: a x
# 2: b y
# 3: c z
df2
#    a     b
# 1: a new_x
# 2: c new_z

l <- match(df1$a, df2$a, nomatch = 0)
df1$b[l != 0] <- df2$b[l]

df1
#    a     b
# 1: a new_x
# 2: b     y
# 3: c new_z
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...