【问题标题】:Elegant way to merge data frames in R?在 R 中合并数据框的优雅方法?
【发布时间】:2017-03-07 00:49:11
【问题描述】:

我想获取数据框的唯一行,然后将其与另一行属性连接。然后我希望能够计算品种的数量,例如特定类型或来源的独特水果的数量。

第一个数据框有我的水果列表:

fruits <- read.table(header=TRUE, text="shop    fruit
                    1   apple
                    2   orange
                    3   apple
                    4   pear
                    2   banana
                    1   banana
                    1   orange
                    3   banana")

第二个数据框有我的属性:

fruit_class <- read.table(header=TRUE, text="fruit  type    origin
apple   pome    asia
                      banana  berry   asia
                      orange  citrus  asia
                      pear    pome    newguinea")

这是我对这个问题的笨拙解决方案:

fruit <- as.data.frame(unique(fruit[,2])) #get a list of unique fruits
colnames(fruit)[1] <- "fruit" #this won't rename the column and I don't know why...
fruit_summary <- join(fruits, fruit_class, by="fruit" #create a data frame that I can query
count(fruit_summary, "origin") #for eg, summarise the number of fruits of each origin

所以我的主要问题是:如何更优雅地表达这一点(即单行而不是 3 行)? 其次:为什么不允许我重命名列?

提前致谢

【问题讨论】:

  • 在基地:aggregate(fruit ~ origin, merge(fruits, fruit_class), FUN = length) 或 dplyr:fruits %&gt;% left_join(fruit_class) %&gt;% count(origin)
  • 您的基本代码告诉我有 12 个来自亚洲的水果和 4 个来自新几内亚的水果,所以它总结了 fruits$shop 列(我不想使用)。结果应该是 3 种来自亚洲的水果(苹果、香蕉和橙子)和一种来自新几内亚(梨)的水果。
  • 我得到 7 和 1,但如果您只想计算来自 fruit_class 的来源,请使用 count(fruit_class, origin)。如果您想确保它们首先在fruits 中,请使用fruit_class %&gt;% semi_join(fruits) %&gt;% count(origin),在这种情况下它将返回相同的内容。也不是求和shop;他们在计算行数。
  • 另见 count aggregationjoining 的规范帖子。

标签: r dataframe plyr summarize


【解决方案1】:

只是做

table(fruit_class$fruit, fruit_class$origin)

给你

       asia newguinea
apple     1         0
banana    1         0
orange    1         0
pear      0         1

您可以将区域编号与colSums() 相加。我想不出需要fruits 数据框的原因,因为如果这里有一个水果不在fruit_class 中,那么无论如何都没有它的原始数据。

顺便说一下,在您的代码示例中,colnames(fruit)[1] &lt;- "fruit" 应该可以工作,但只需要 colnames(fruit) &lt;- "fruit",因为无论如何,列名只有 1 个元素长。

【讨论】:

    【解决方案2】:

    这是data.table 解决方案。

    library(data.table)
    setDT(fruit_class)[, uniqueN(fruit), by=type]
    #      type V1
    # 1:   pome  2
    # 2:  berry  1
    # 3: citrus  1
    
    setDT(fruit_class)[, uniqueN(fruit), by=origin]
    #       origin V1
    # 1:      asia  3
    # 2: newguinea  1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 2017-12-25
      • 2022-01-14
      • 1970-01-01
      相关资源
      最近更新 更多