r - 条件

时间:2018-05-15 23:38:03

标签: r dataframe insert rows

最近我一直在尝试使用2个数据帧生成某个输出,但似乎我的R经验仍然不足以做到这一点。我花了很多时间,但无法找到答案如何做到这一点。欢迎任何有关以下任务的帮助。

我有两个数据集base_dfcompare_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))插入值val1val2

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_dfarrange不会随行数增加。也许可以使用var1函数完成?

以下是简化示例:

var2

Simplified example result below

2 个答案:

答案 0 :(得分:2)

使用的解决方案。假设原始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