我有一个数据框' clinDF'我必须根据另一个更新,解析DF',通过R.让我们说:
#clinDF
P1 P2 P3 P4
A M F M M
B H M L M
C 3 4 1 0
#parsingDF
feat var col
[1] A M #B3E2CD
[2] A F #E41A1C
[3] B H #A6CEE3
[4] B M #FCCDE5
[5] B L #8DD3C7
[6] C 0 #BC80BD
[7] C 1 #A6CEE3
[8] C 3 #B3E2CD
[9] C 4 #E41A1C
我的目标是解析clinDF
,以便获得相应的col
:
#out:
P1 P2 P3 P4
A #B3E2CD #E41A1C #B3E2CD #B3E2CD
B #A6CEE3 #FCCDE5 #8DD3C7 #FCCDE5
C #B3E2CD #E41A1C #A6CEE3 #BC80BD
理想情况下,我希望通过设置clinDF
,使代码尽可能通用,并且{strong>不会更改clinDF[clinDF==3]=#B3E2CD
中的所有。有没有比使用两个for
循环更好的方法来逐行和逐列读取?
提前谢谢
答案 0 :(得分:3)
以下是使用tidyverse
中的函数的解决方案。 clinDF2
将是最终输出。
# Create example dataframes
clinDF <- read.table(text = " P1 P2 P3 P4
A M F M M
B H M L M
C 3 4 1 0",
header = TRUE, stringsAsFactors = FALSE)
parsingDF <- read.table(text = "feat var col
A M '#B3E2CD'
A F '#E41A1C'
B H '#A6CEE3'
B M '#FCCDE5'
B L '#8DD3C7'
C 0 '#BC80BD'
C 1 '#A6CEE3'
C 3 '#B3E2CD'
C 4 '#E41A1C'",
header = TRUE, stringsAsFactors = FALSE)
# Load packages
library(tidyverse)
# Process the data
clinDF2 <- clinDF %>%
rownames_to_column("feat") %>%
gather(Group, var, -feat) %>%
left_join(parsingDF, by = c("feat", "var")) %>%
select(-var) %>%
spread(Group, col) %>%
remove_rownames() %>%
column_to_rownames("feat")
答案 1 :(得分:2)
我们可以使用data.table
执行此操作。由于两个数据集都是矩阵,melt
'clinDF'到'long'格式,转换为data.table
(setDT/as.data.table
),加入on
'feat / var''数据集的Var1 / value'列,并使用acast
中的reshape2
将其重新整理为“宽”格式
library(data.table)
library(reshape2)
dM <- melt(clinDF)
setDT(dM)
acast(as.data.table(parsingDF)[dM, on = .(feat = Var1, var = value)],
feat ~ Var2, value.var = 'col')
# P1 P2 P3 P4
#A "#B3E2CD" "#E41A1C" "#B3E2CD" "#B3E2CD"
#B "#A6CEE3" "#FCCDE5" "#8DD3C7" "#FCCDE5"
#C "#B3E2CD" "#E41A1C" "#A6CEE3" "#BC80BD"
答案 2 :(得分:2)
这是我的解决方案〜
library(Reshape)
library(Reshape2)
Table1=melt(as.matrix(clinDF) )
Table1=merge(Table1,parsingDF,by.x=c('X1','value'),by.y=c('feat','var'),all.x=T)
dcast(Table1, X1~X2, value.var="col")
X1 P1 P2 P3 P4
1 A #B3E2CD #E41A1C #B3E2CD #B3E2CD
2 B #A6CEE3 #FCCDE5 #8DD3C7 #FCCDE5
3 C #B3E2CD #E41A1C #A6CEE3 #BC80BD