如何在新数据框中匹配两组因子水平?

时间:2019-02-08 11:45:48

标签: r tidyr

我的数据框很大,我想导出一个新的数据框,其中包含基于id列的第一个数据的摘要统计信息。

library(tidyverse)
set.seed(123) 
id = rep(c(letters[1:5]), 2)
species = c("dog","dog","cat","cat","bird","bird","cat","cat","bee","bee")
study = rep("UK",10)
freq = rpois(10, lambda=12)
df1 <- data.frame(id,species, freq,study)
df1$id<-sort(df1$id)
df1

df2 <- df1 %>% group_by(id) %>%
  summarise(meanFreq= mean(freq),minFreq=min(freq))
df2

我想使用摘要统计信息将物种名称保留在新的数据框中。但是,如果按ID合并,则会得到多余的行。每个ID我只能有一行,但要附加物种名称。

df3<-merge(df2,df1,by = "id") 

这是它的外观,但是我的真实数据比这里的整洁设置更混乱:

df4 = df3[seq(1, nrow(df3), 2), ]
df4

2 个答案:

答案 0 :(得分:1)

从汇总输出('df2')中,我们可以与原始数据的选定列的distinct行结合起来

library(dplyr)
df2 %>% 
    left_join(df1 %>% 
                distinct(id, species, study), by = 'id')
# A tibble: 5 x 5
#  id    meanFreq minFreq species study
#  <fct>    <dbl>   <dbl> <fct>   <fct>
#1 a         10.5      10 dog     UK   
#2 b         14.5      12 cat     UK   
#3 c         14.5      12 bird    UK   
#4 d         10         7 cat     UK   
#5 e         11         6 bee     UK   

或与base R

使用相同的逻辑
merge(df2,unique(df1[c(1:2, 4)]),by = "id", all.x = TRUE)

答案 1 :(得分:0)

mutate后跟distinct的时间:

df1 %>% group_by(id) %>%
  mutate(meanFreq = mean(freq), minFreq = min(freq)) %>%
  distinct(id, .keep_all = T)

现在实际上有两种可能性:idspecies在您的df中基本上是相同的,一个只是另一个的标签,或者相同的id可以有多个种类。

如果是后者,则需要用distinct(id, species, .keep_all = T)替换最后一行。

这会让您:

# A tibble: 5 x 6
# Groups:   id [5]
  id    species  freq study meanFreq minFreq
  <fct> <fct>   <int> <fct>    <dbl>   <dbl>
1 a     dog        10 UK        10.5      10
2 b     cat        17 UK        14.5      12
3 c     bird       12 UK        14.5      12
4 d     cat        13 UK        10         7
5 e     bee         6 UK        11         6

如果您唯一的目标是保留species并且它们确实与id相同,则也可以将其包含在group_by中:

df1 %>% group_by(id, species) %>%
      summarise(meanFreq = mean(freq), minFreq = min(freq))

这将删除studyfreq-如果需要保留它们,则可以再次将summarise替换为mutate,然后再替换distinct .keep_all = T参数。