【问题标题】:Easy way of "adding" two large tables in R?在 R 中“添加”两个大表的简单方法?
【发布时间】:2013-05-01 05:39:12
【问题描述】:

有没有一种简单的方法可以在 R 的两个大表中添加每个类别的计数?

...表中的值并不完全相同(尽管它们大部分会重叠):

我正在尝试做的小例子。设置一些数据:

  x1 <- c(5, 3, 3, 6, 3, 3, 5, 5, 11, 2, 4, 9, 3, 5, 8, 2, 8, 5, 4, 8)
  x2 <- c(6, 10, 9, 17, 6, 7, 8, 11, 5, 12, 14, 5, 11, 7, 7)

  table(x1)
x1
 2  3  4  5  6  8  9 11 
 2  5  2  5  1  3  1  1 

 table(x2)
x2
 5  6  7  8  9 10 11 12 14 17 
 2  2  3  1  1  1  2  1  1  1 

现在我想合并这些表,就像我已经完成 table(c(x1,x2)) 一样,得到:

 2  3  4  5  6  7  8  9 10 11 12 14 17 
 2  5  2  7  3  3  4  2  1  3  1  1  1 

但现在想象一下 x1 和 x2 已经消失了(而且真的很大,所以我真的 想从表中重新创建它们并实际执行table(c(x1,x2))), 我想要的只是拿表t1t2 并添加它们的(通常非常大)计数......我可以通过几种非常笨重的方式来做到这一点。

但是,这似乎应该既很常见又很容易解决 问题(确实,我认为t1 + t2 应该适用于具有类别的表 相同类型)但搜索我能想到的每个搜索词的问题 什么都没找到。

我是否错过了一种非常简单明了的方法?

编辑:

为了澄清,这样的事情(我做过)对于必须做的事情并不“简单明了” 是一个非常常见的表格操作:

 m <- merge(t1,t2,by.x="x1",by.y="x2",all=TRUE)
 m[is.na(m)] <- 0
 oo <- order(m$x1)
 t12 <- m[oo,2]+m[oo,3]
 names(t12) <- m[oo,1]

特别是,这实际上并不比蛮力方法更简单也更容易遵循。

【问题讨论】:

  • 你应该看看merge
  • @PaulHiemstra 我在发帖之前做过。我也玩了一段时间。我没有看到做我想做的事的好方法(比用蛮力做更容易)。可能我错过了那里的某些东西,但在那种情况下......我需要更多的提示。
  • 如果您使用数据框而不是表格,您的生活会轻松很多。表只是命名向量,一般来说,用于对齐和组合命名向量的 R 函数很少,而用于数据帧的函数很多。
  • @hadley 谢谢;我使用表格的原因无非是table 的输出;我很乐意根据需要as.data.frame 他们,但是(在组合它们之后)命名向量足以满足我的需要;作为一个更广泛的原则,我认为这是一个很好的建议,但我自己很少使用表格。

标签: r aggregate


【解决方案1】:

dplyr中:

library(dplyr)
x1 <- c(5, 3, 3, 6, 3, 3, 5, 5, 11, 2, 4, 9, 3, 5, 8, 2, 8, 5, 4, 8)
x2 <- c(6, 10, 9, 17, 6, 7, 8, 11, 5, 12, 14, 5, 11, 7, 7)

# Transform "Tables" to DataFrames & standardize column names
df1 <- as.data.frame(table(x1)) %>% select(x = x1, Freq)
df2 <- as.data.frame(table(x2)) %>% select(x = x2, Freq)  

# Merge tables & aggregate results
Ttldf <- bind_rows(df1, df2) %>% group_by(x) %>% summarise(TtlFreq = sum(Freq))

对于总结和管道 Vignette 的简要介绍是一个很好的资源:@​​987654321@

有关快速使用摘要以进一步发挥最佳效果的方法的更多信息,Markham 的教程非常有帮助:https://rpubs.com/justmarkham/dplyr-tutorial

【讨论】:

    【解决方案2】:

    使用tapply的另一种方式:

    tapply(c(t1,t2), names(c(t1,t2)), sum)
    # 10 11 12 14 17  2  3  4  5  6  7  8  9 
    #  1  3  1  1  1  2  5  2  7  3  3  4  2 
    

    这里是如果你想要一个排序的输出:

    w <- c(t1,t2)
    # edit: Following G.Grothendieck's suggestion to simplify it further
    tapply(w, as.numeric(names(w)), sum)
    #  2  3  4  5  6  7  8  9 10 11 12 14 17 
    #  2  5  2  7  3  3  4  2  1  3  1  1  1 
    

    【讨论】:

    • 啊,整洁。是的,需要排序输出。第二种方式可以毫不费力地很好地扩展到许多表。
    【解决方案3】:

    正如@PaulHiemstra 所说,merge应该完成这项工作。我不太熟悉它,但这段代码应该可以工作(尽管可能有更有效的方法......)

    x1 <- c(5, 3, 3, 6, 3, 3, 5, 5, 11, 2, 4, 9, 3, 5, 8, 2, 8, 5, 4, 8)
    x2 <- c(6, 10, 9, 17, 6, 7, 8, 11, 5, 12, 14, 5, 11, 7, 7)
    
    tx1 <- table(x1)
    tx2 <- table(x2)
    
    df1 <- data.frame(names=names(tx1),values=as.vector(tx1))
    df2 <- data.frame(names=names(tx2),values=as.vector(tx2))
    
    mdf12 <- merge(df1,df2,by="names",all=TRUE)
    mdf12[is.na(mdf12)] <- 0
    
    counts <- mdf12[,2] + mdf12[,3]
    names(counts) <- mdf12[,1]
    
    counts[order(as.numeric(names(counts)))]
    table(c(x1,x2))
    

    我不喜欢is.na 步骤,但我不知道如何实现,首先有0 而不是NA

    【讨论】:

    • 谢谢,是的,我实际上做了一些与此非常接近的事情,但是对于必须非常频繁地使用 table 的操作来说,这似乎非常复杂。
    • 好的,那么抱歉带来了。也许我可以稍后删除这篇文章,因为你编辑了你之前已经尝试过那个复杂解决方案的帖子,@Arun 发布了一个合适的解决方案 (+1)。
    • 这里的错是我的;您的答案涵盖了 a 方法,并且在没有我后来在编辑中包含的信息的情况下,这是一个合理的答案。我相应地投了赞成票。
    猜你喜欢
    • 1970-01-01
    • 2015-08-14
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    相关资源
    最近更新 更多