[英]R: Extract Rows from One Data Frame, Based on Column Names Matching Values from Another Data Frame
[英]R: Copying values from one to another data frame based on column value
我有两个数据框:
data_frame1
cmb | value | par_1 | par_2 | par_3
0 0.3 XXX YYYY ZZZ
data_frame2
cmb | value | par_1 | par_2 | par_3
1 0.333 XXX YYYY ZZZ
1 0.45 XXX YYYY ZZZ
2 10.3 XXX YYYY ZZZ
3 3.4 XXX YYYY ZZZ
其中参数par_1
、 par_2
和par_3
。
我只想将每个cmb
值的值从data_frame1
复制到data_frame2
,同时从cmb
获取值(其他参数保留它们的值)。 预期 output:
cmb | value | par_1 | par_2 | par_3
1 0.333 XXX YYYY ZZZ
1 0.45 XXX YYYY ZZZ
1 0.3 XXX YYYY ZZZ #same value, par_1.. only cmb=1
2 10.3 XXX YYYY ZZZ
2 0.3 XXX YYYY ZZZ #same value, par_1.. only cmb=2
3 3.4 XXX YYYY ZZZ
3 0.3 XXX YYYY ZZZ #same value, par_1.. only cmb=3
这是一个data.table
选项
> setDT(df2)[, rbind(.SD, subset(df1, select = -cmb)), cmb]
cmb value par_1 par_2 par_3
1: 1 0.333 XXX YYYY ZZZ
2: 1 0.450 XXX YYYY ZZZ
3: 1 0.300 XXX YYYY ZZZ
4: 2 10.300 XXX YYYY ZZZ
5: 2 0.300 XXX YYYY ZZZ
6: 3 3.400 XXX YYYY ZZZ
7: 3 0.300 XXX YYYY ZZZ
数据
> dput(df1)
structure(list(cmb = 0L, value = 0.3, par_1 = "XXX", par_2 = "YYYY",
par_3 = "ZZZ"), class = "data.frame", row.names = c(NA, -1L
))
> dput(df2)
structure(list(cmb = c(1L, 1L, 2L, 3L), value = c(0.333, 0.45,
10.3, 3.4), par_1 = c("XXX", "XXX", "XXX", "XXX"), par_2 = c("YYYY",
"YYYY", "YYYY", "YYYY"), par_3 = c("ZZZ", "ZZZ", "ZZZ", "ZZZ"
)), class = "data.frame", row.names = c(NA, -4L))
这是一个基本的 R 选项,它根据df2
中的唯一cmb
值复制df1
中的行。
vals <- unique(df2$cmb)
df3 <- rbind(df2, transform(df1[rep(seq(nrow(df1)), length(vals)),], cmb = vals))
rownames(df3) <- NULL
df3[order(df3$cmb), ]
# cmb value par_1 par_2 par_3
#1 1 0.333 XXX YYYY ZZZ
#2 1 0.450 XXX YYYY ZZZ
#5 1 0.300 XXX YYYY ZZZ
#3 2 10.300 XXX YYYY ZZZ
#6 2 0.300 XXX YYYY ZZZ
#4 3 3.400 XXX YYYY ZZZ
#7 3 0.300 XXX YYYY ZZZ
或者在tidyverse
中实现相同的逻辑:
library(dplyr)
library(tidyr)
df1 %>%
uncount(n_distinct(df2$cmb)) %>%
mutate(cmb = unique(df2$cmb)) %>%
bind_rows(df2) %>%
arrange(cmb)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.