如何使用查找表替换data.table列中的值? [R]

时间:2019-01-22 21:35:04

标签: r metadata lookup

我有一个钥匙和一个巨大的元数据表。元数据表中有一列,其中包含诸如以下的值:

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。我想做的是用第二个表的第二列中的相应缩写替换第一张表的列中的所有条目。

问题是,当我听取highly-popular post的建议来演示如何执行此操作时,我最终以某种方式最终得到一个表,该表具有{{1} }栏;换句话说,该表中的所有其他数据都将被删除,但被替换的数据除外。从好的方面来说,替换是可行的,但是现在我有了一个完全空白的表,只保留标题。

这是我的代码的样子。我提供了我尝试过的最佳回答者提供的两种解决方案。

body_site

2 个答案:

答案 0 :(得分:1)

这是一个解决方案:

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

答案 1 :(得分:1)

  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……下一部分仅在没有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')