我是R编程的新手,我想知道是否可以通过比较2个文件来更新值。
例如,我有主表df_table1:
Date Metric1 Metric2 Metric3
1/1/2018 25 4.6 49
2/1/2018 6 3.6 67
3/1/2018 18 2.6 36
4/1/2018 56 3.6 29
我要遍历文件夹中的各种文件,并且碰巧有一个文件,其中还包含一些具有相同日期值df_table2的重叠数据:
Date Metric1 Metric2 Metric3
3/1/2018 19 2.9 47
4/1/2018 78 5.7 35
5/1/2018 46 3.3 29
通常的组合数据文件的方法是使用rbind(),但我相信这将为df_table2中找到的2个日期创建重复值。
是否可以有效地进行比较,以检查所有后续文件中是否存在重叠的日期,并根据df_table1中的日期替换其对应的值?
理想情况下,如果df_table2中的所有指标的值都大于df_table1中的值,那么有一种方法仅做替换会更好。
最后,我希望最终输出通过某种特殊的rbind()函数将df_table1和df_table2组合在一起,并从df_table2更新值,而不会重复:
Date Metric1 Metric2 Metric3
1/1/2018 25 4.6 49
2/1/2018 6 3.6 67
3/1/2018 19 2.9 47 #updated from df_table2
4/1/2018 78 5.7 35 #updated from df_table2
5/1/2018 46 3.3 29 #new value from df_table2
谢谢!
答案 0 :(得分:1)
让我们先定义数据(为了将来,请您自己做,以使人们更容易地为您提供帮助):
df_table1= data.frame(Date=c('1/1/2018','2/1/2018','3/1/2018','4/1/2018'),
Metric1 = c(25,6,18,56),
Metric2 = c(4.6,3.6,2.6,3.6),
Metric3 = c(49,67,36,29))
df_table2= data.frame(Date=c('3/1/2018','4/1/2018','5/1/2018'), Metric1 = c(19,78,46),
Metric2 = c(2.9,5.7,3.3),
Metric3 = c(48,35,29))
接下来,我将合并表,然后重新创建所需的变量。我为您写的第一个,其他的应该很容易。您不仅可以使用is.na()
,还可以比较哪个变量更大,然后选择所需的变量。
df = merge(df_table1, df_table2, by='Date', all=TRUE)
df$Metric1 = df$Metric1.y
df$Metric1[is.na(df$Metric1)] = df$Metric1.x[is.na(df$Metric1)]
df
Date Metric1.x Metric2.x Metric3.x Metric1.y Metric2.y Metric3.y Metric1
1 1/1/2018 25 4.6 49 NA NA NA 25
2 2/1/2018 6 3.6 67 NA NA NA 6
3 3/1/2018 18 2.6 36 19 2.9 48 19
4 4/1/2018 56 3.6 29 78 5.7 35 78
5 5/1/2018 NA NA NA 46 3.3 29 46
答案 1 :(得分:1)
使用dplyr
:
rbind(df_table1,df_table2) %>% group_by(Date) %>% filter(Metric1==max(Metric1))
# A tibble: 5 x 4
# Groups: Date [5]
Date Metric1 Metric2 Metric3
<chr> <dbl> <dbl> <dbl>
1 1/1/2018 25. 4.60 49.
2 2/1/2018 6. 3.60 67.
3 3/1/2018 19. 2.90 48.
4 4/1/2018 78. 5.70 35.
5 5/1/2018 46. 3.30 29.
请注意,这假设如果一个表中的Metric1大于另一个表中的Metric1,则所有其他度量也将相同。我不清楚如果不是这种情况会发生什么。
这是奇怪的代码,它将在两个表中的每个日期都保留一行,保留其中所有指标都大于另一行的任一行,或者,如果没有一行与该规则匹配,它将保留该行来自表1:
首先,让我们稍微更改一下数据:
df_table1= data.frame(Date=c('1/1/2018','2/1/2018','3/1/2018','4/1/2018'),
Metric1 = c(25,6,18,56),
Metric2 = c(4.6,3.6,2.6,6.3),
Metric3 = c(49,67,36,29), stringsAsFactors = FALSE)
df_table2= data.frame(Date=c('3/1/2018','4/1/2018','5/1/2018'), Metric1 = c(19,78,46),
Metric2 = c(2.9,5.7,3.3),
Metric3 = c(48,35,29), stringsAsFactors = FALSE)
现在1月4日行的指标2会比第一行高,而其他指标则比另一行高。
rbind(df_table1,df_table2) %>%
group_by(Date) %>%
mutate(keeper=(Metric1==max(Metric1) & Metric2==max(Metric2) & Metric3==max(Metric3))) %>%
group_by(Date,keeper) %>%
filter(row_number()==1) %>%
group_by(Date) %>% add_count() %>%
mutate(keeper=ifelse(n==1,TRUE,keeper)) %>%
filter(keeper) %>% select(-keeper, -n)
# A tibble: 5 x 4
# Groups: Date [5]
Date Metric1 Metric2 Metric3
<chr> <dbl> <dbl> <dbl>
1 1/1/2018 25. 4.60 49.
2 2/1/2018 6. 3.60 67.
3 4/1/2018 56. 6.30 29.
4 3/1/2018 19. 2.90 48.
5 5/1/2018 46. 3.30 29.
我敢肯定,有一种更优雅的方法可以实现这一目标,但是我不知道它是什么-我经过大量的尝试和错误来解决这个问题...
最后,如果您决定只保留table1版本(如果存在重复的日期),而与度量标准无关,请执行以下操作:
rbind(df_table1,df_table2) %>% filter(!duplicated(Date))
Date Metric1 Metric2 Metric3
1 1/1/2018 25 4.6 49
2 2/1/2018 6 3.6 67
3 3/1/2018 18 2.6 36
4 4/1/2018 56 6.3 29
5 5/1/2018 46 3.3 29
答案 2 :(得分:0)
这应该对您有用
library(dplyr)
df_new <- df_table1%>%
anti_join(df_table2, by = c('Date'))%>%
rbind(data= . ,df_table2)