最近我一直在尝试使用2个数据帧生成某个输出,但似乎我的R经验仍然不足以做到这一点。我花了很多时间,但无法找到答案如何做到这一点。欢迎任何有关以下任务的帮助。
我有两个数据集base_df
和compare_df
。需要使用以下规则在compare_df
中插入base_df
中的特定元素(单元格):
a)来自id
的{{1}}列中的元素和来自base_df
的{{1}}中的元素应该相等
b)如果数字来自xx,yy或zz,则在使用分隔符id
为ex分隔字符后。 " 1.5_2.5"可以保存在2个单独的变量中,例如compare_df
= 1.5和_
= 2.5,所以:
如果val1
,则val2
中的第1行和第2行之间的(compare_df$val1 > base_df$var1 & compare_df$val1 < lead(base_df$var1)) & (compare_df$val2 > base_df$var2 & compare_df$val2 < lead(base_df$var2))
插入值val1
和val2
。
c)使用完成交换的变量的名称,在本例中为ex。创建新变量,让我们说compare_df
,并为base_df
中新创建的第2行等于&#34; xx&#34;分配给此变量的值。
注意:ind
有许多列,例如base_df
,也需要完成此过程。因此,检查compare_df
中除id之外的所有列的条件。
基本上,xx,yy and zz
中的每一行信息都应与compare_df
中的所有行进行比较,并查看是否满足条件。可能有多个匹配项。应保留行的原始顺序,因此无法使用compare_df
,因为base_df
和arrange
不会随行数增加。也许可以使用var1
函数完成?
以下是简化示例:
var2
答案 0 :(得分:2)
使用tidyverse的解决方案。假设原始base_df
中的行在新数据框的old
列中被称为ind
。目前尚不清楚您的过滤条件是什么,但我尝试匹配您的预期输出。 new_df
是最终输出。
library(tidyverse)
compare_df2 <- compare_df %>%
gather(ind, value, -id) %>%
separate(value, into = c("var1", "var2"), sep = "_", convert = TRUE)
new_df <- base_df %>%
mutate(ind = "org") %>%
bind_rows(compare_df2) %>%
select(id, ind, var1, var2) %>%
arrange(id, var1, var2) %>%
filter(var2 > var1) %>%
filter(row_number() != which(var2 < lag(var2)) - 1)
new_df
# id ind var1 var2
# 1 a org 1.0 2.0
# 2 a xx 1.5 2.5
# 3 a org 3.0 4.0
# 4 a zz 3.5 4.5
# 5 a org 5.0 6.0
# 6 a org 7.0 8.0
# 7 a org 9.0 10.0
# 8 b org 11.0 12.0
# 9 b org 13.0 14.0
# 10 b org 15.0 16.0
# 11 b zz 15.5 16.5
# 12 b org 17.0 18.0
# 13 b xx 17.5 18.5
# 14 b org 19.0 20.0
答案 1 :(得分:1)
这是一个可能的整洁解决方案:
base_df <- data.frame(id = c("a", "a", "a", "a", "a", "b", "b", "b", "b", "b"),
var1 = seq(1,20, by = 2),
var2 = seq(2,21, by = 2))
compare_df <- data.frame(id = c("a", "b"),
xx = c("1.5_2.5", "17.5_18.5"),
yy = c("3.5_2.5", "12.5_18.5"),
zz = c("3.5_4.5", "15.5_16.5"))
# Reshape compare_df to long
compare_df <- gather(compare_df, ind, value, -id)
# Sep the compare_df by "_"
compare_df <- separate(compare_df, col=value, into = c("var1", "var2"), sep = "_")
# Add the "org" column to base_df
base_df$ind <- "org"
# Combine and sort the dfs
final_df2 <- rbind(base_df, compare_df) %>%
arrange(id, var1)
# I think you wanted to only keep compare_df where var1 was < var2?
final_df2 <- filter(final_df2, var1 < var2)
final_df2
id var1 var2 ind
1 a 1 2 org
2 a 1.5 2.5 xx
3 a 3 4 org
4 a 3.5 4.5 zz
5 a 5 6 org
6 a 7 8 org
7 b 11 12 org
8 b 12.5 18.5 yy
9 b 13 14 org
10 b 15 16 org
11 b 15.5 16.5 zz
12 b 17 18 org
13 b 17.5 18.5 xx
14 b 19 20 org