R代码无法根据相同的值合并列中的数据(非重复)

时间:2019-06-10 23:28:14

标签: r dplyr

我正在尝试使用dplyr对一些小数据(数据帧)进行数据整理,以消除重复记录,如果id出现两次,则结果记录将包含相同的值(如果它们都相同),或者包含NA其中一条记录存在差异。例如,如果我有df:

id       date        amount     tag
---      ----        ------     ---
1        2018-01-03  10         big
2        2019-01-16  20         small
3        2020-01-05  30         big
3        2001-03-04  30         big
1        2018-01-03  5          big

结果应如下所示:

id       date        amount     tag
---      ----        ------     ---
1        2018-01-03  NA         big
2        2019-01-16  20         small
3        NA          30         big

基于我在堆栈溢出时发现的其他答案,我尝试了各种使用summarise_all的方法,包括:

new_df <- df %>% group_by(id) %>% summarise_all(function(x) ifelse(all(x[1] == x),x[1],NA))
new_df <- df %>% group_by(id) %>% summarise_all(list(~ if(all(.[1] == .)) .[1] else NA))
new_df <- df %>% group_by(id) %>% summarise_all(funs(if(all(.[1] == .)) .[1] else NA))

由于我可以自己将ifelse(all(x[1] == x),x[1],NA)与向量一起使用,并且效果很好,所以我认为可以与summarise_all一起使用。但是,当我将其与summarise_all或上面显示的其他变体一起使用时,会出现错误:

Error in summarise_impl(.data, dots): Column `date` can't promote group 2 to character

我怀疑我只需要对代码进行一些细微调整就可以使其正常工作,但是我整天都在工作,我不知道为什么它不工作...所以任何社区提供的帮助将不胜感激。这是我第一次真正问到堆栈溢出问题,因为我几乎总是可以从其他人的问题中找到答案:-)非常感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

首先,解决方案:

d %>% 
  group_by(id) %>% 
  summarise_all(~if(n_distinct(.) == 1) first(.) else c(NA, .)[1])

这实际上有点棘手。您可能会想简单地写:

d %>% 
  group_by(id) %>% 
  summarise_all(~if(n_distinct(.) == 1) first(.) else NA)

这只是if (all ...) ... else ...的替代方法,它使用了更多的dplyr函数。

但是,dplyr不喜欢简单地给NA,而是需要特定于类型。例如。您需要提供NA_character_NA_integer_等以匹配正确的数据类型。这就是您的代码失败的原因,该错误表明第2组(在这种情况下为id == 2)没有被“提升”为字符。这意味着NA列中提供的Date不会被强制转换为字符,并且无法创建新列。

由于您不想编写所有正确的NA类型的代码,因此我在这里使用了一些技巧。使用c(NA, .)[1]NA的值与原始变量组合在一起会将NA强制转换为正确的类型,然后使用该类型。您可能还可以使用其他技巧来获取正确的NA