我有两个数据帧具有相同的rownames和columnnames,但顺序不同。价值也不同。
df1
:
name S1 S2 S3 S4 S5 S6 S7
ABC 56 67 90 78 45 34 23
HJG 12 32 13 99 55 89 25
KLI 88 36 95 21 66 74 45
JHU 32 55 65 77 88 16 40
DFR 65 90 87 11 98 67 37
df2
:
name S1 S3 S5 S2 S4 S7 S6
DFR 0 -1 -1 1 -2 1 -1
JHU 1 -2 2 1 2 0 1
HJG -2 0 1 1 -2 -2 -1
ABC -1 2 -2 1 0 1 0
KLI 2 1 0 -1 1 0 -2
我想根据df1
中的值将df2
数据框拆分为两组。
df1
的Group1应基于df2
df1
的Group2应基于df2
例如:
Group1: Group2:
name S1 S3 S4 name S2 S5 S6 S7
KLI 88 95 21 KLI 36 66 74 45
同样,我需要重复其他所有名字。谁能告诉我如何在R或Python中做到这一点?
答案 0 :(得分:2)
下面的代码将为您提供带有组标记的长格式数据框。代码的工作原理如下:
gather
),然后加入它们(使用left_join
)。group
中的值创建df2
列。使用dplyr
管道运算符(%>%
)将所有这些步骤链接在一起。
library(tidyverse)
df.new = df1 %>% gather(key, value, -name) %>%
left_join(df2 %>% gather(key, value, -name), by=c("name","key"), suffix=c("1","2")) %>%
mutate(group = ifelse(value2 >=1, "Group 1", "Group 2")) %>%
select(name, key, value=value1, group) %>%
arrange(group, name, key)
name key value group 1 ABC S2 67 Group 1 2 ABC S3 90 Group 1 3 ABC S7 23 Group 1 ... 13 KLI S1 88 Group 1 14 KLI S3 95 Group 1 15 KLI S4 21 Group 1 ... 32 KLI S2 36 Group 2 33 KLI S5 66 Group 2 34 KLI S6 74 Group 2 35 KLI S7 45 Group 2
如果您确实希望每个组位于单独的数据框中,您可以在链的末尾split
group
,这将为您提供包含两个数据框的列表,每个级别一个group
:
df.list = df1 %>% gather(key, value, -name) %>%
left_join(df2 %>% gather(key, value, -name), by=c("name","key"), suffix=c("1","2")) %>%
mutate(group = ifelse(value2 >=1, "Group 1", "Group 2")) %>%
select(name, key, value=value1, group) %>%
arrange(group, name, key) %>%
split(.$group)
将输出保存到csv
或xlsx
文件:
对于我们有一个数据框的第一个例子:
write.csv(df.new, "file_name.csv", row.names=FALSE)
library(xlsx)
write.xlsx(df.new, "file_name.xlsx", row.names=FALSE)
对于第二个示例,我们有一个包含多个数据帧的列表,我们将每个数据帧写入单独的csv文件。对于Excel文件,我们将两个数据框写入同一Excel工作簿中的不同工作表:
# Write to two different csv files
map(names(df.list), function(x) write.csv(df.list[[x]], paste0(x,".csv"), row.names=FALSE))
# Write to two different sheets in the same Excel file
library(xlsx)
map(names(df.list), function(x) write.xlsx(df.list[[x]], "my_file.xlsx", sheet=x, append=TRUE, row.names=FALSE))