【问题标题】:Merge dataframes, different lengths合并数据帧,不同的长度
【发布时间】:2012-12-15 15:59:08
【问题描述】:

我想添加来自dat2的变量:

          concreteness familiarity typicality
amoeba            3.60        1.30       1.71
bacterium         3.82        3.48       2.13
leech             5.71        1.83       4.50

dat1

    ID  variable value
1    1    amoeba     0
2    2    amoeba     0
3    3    amoeba    NA
251  1 bacterium     0
252  2 bacterium     0
253  3 bacterium     0
501  1     leech     1
502  2     leech     1
503  3     leech     0

给出以下输出:

    X ID  variable value concreteness familiarity typicality
1   1  1    amoeba     0         3.60        1.30       1.71
2   2  2    amoeba     0         3.60        1.30       1.71
3   3  3    amoeba    NA         3.60        1.30       1.71
4 251  1 bacterium     0         3.82        3.48       2.13
5 252  2 bacterium     0         3.82        3.48       2.13
6 253  3 bacterium     0         3.82        3.48       2.13
7 501  1     leech     1         5.71        1.83       4.50
8 502  2     leech     1         5.71        1.83       4.50
9 503  3     leech     0         5.71        1.83       4.50

如您所见,dat1 中的信息必须在 dat2 中的多行中复制。

这是我失败的尝试:

dat3 <- merge(dat1, dat2, by=intersect(dat1$variable(dat1), dat2$row.names(dat2)))

给出以下错误:

Error in as.vector(y) : attempt to apply non-function

请在此处找到复制示例:

dat1:

structure(list(ID = c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), variable = structure(c(1L, 
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("amoeba", "bacterium", 
"leech", "centipede", "lizard", "tapeworm", "head lice", "maggot", 
"ant", "moth", "mosquito", "earthworm", "caterpillar", "scorpion", 
"snail", "spider", "grasshopper", "dust mite", "tarantula", "termite", 
"bat", "wasp", "silkworm"), class = "factor"), value = c(0L, 
0L, NA, 0L, 0L, 0L, 1L, 1L, 0L)), .Names = c("ID", "variable", 
"value"), row.names = c(1L, 2L, 3L, 251L, 252L, 253L, 501L, 502L, 
503L), class = "data.frame")

数据2:

structure(list(concreteness = c(3.6, 3.82, 5.71), familiarity = c(1.3, 
3.48, 1.83), typicality = c(1.71, 2.13, 4.5)), .Names = c("concreteness", 
"familiarity", "typicality"), row.names = c("amoeba", "bacterium", 
"leech"), class = "data.frame")

【问题讨论】:

    标签: r merge


    【解决方案1】:

    您可以向 dat2 添加一个连接变量,然后使用合并:

    dat2$variable <- rownames(dat2)
    merge(dat1, dat2)
       variable ID value concreteness familiarity typicality
    1    amoeba  1     0         3.60        1.30       1.71
    2    amoeba  2     0         3.60        1.30       1.71
    3    amoeba  3    NA         3.60        1.30       1.71
    4 bacterium  1     0         3.82        3.48       2.13
    5 bacterium  2     0         3.82        3.48       2.13
    6 bacterium  3     0         3.82        3.48       2.13
    7     leech  1     1         5.71        1.83       4.50
    8     leech  2     1         5.71        1.83       4.50
    9     leech  3     0         5.71        1.83       4.50
    

    【讨论】:

    • 此答案适用于显示的示例数据,但如果有的话,将删除 dat1 中所有不匹配的行。
    【解决方案2】:

    @agstudy 的回答没有错,但您可以通过创建一个匿名临时文件来实际修改 dat2。添加 X 类似:

    > merge(cbind(dat1, X=rownames(dat1)), cbind(dat2, variable=rownames(dat2)))
       variable ID value   X concreteness familiarity typicality
    1    amoeba  1     0   1         3.60        1.30       1.71
    2    amoeba  2     0   2         3.60        1.30       1.71
    3    amoeba  3    NA   3         3.60        1.30       1.71
    4 bacterium  1     0 251         3.82        3.48       2.13
    5 bacterium  2     0 252         3.82        3.48       2.13
    6 bacterium  3     0 253         3.82        3.48       2.13
    7     leech  1     1 501         5.71        1.83       4.50
    8     leech  2     1 502         5.71        1.83       4.50
    9     leech  3     0 503         5.71        1.83       4.50
    

    【讨论】:

    • 类似的问题。我有多个数据框,它们都是“每周”记录。我想将它们全部合并并将它们绘制到一个数据框中。我将如何合并它们?
    • @kiwicomb123 在这里和 agstudy 的回答中,关键是在每个数据框中都有一个同名的列,它将结果联系在一起。 variable 已存在于 dat1 中,因此将其添加到 dat2 以进行合并。 X 添加到 dat1 只是为了匹配问题中的输出。 (请注意,此处修改后的数据框中除了variable 之外没有其他列名共有,因此merge 与默认的by 参数一起使用。)
    【解决方案3】:

    试试这个:

    merge(dat1, dat2, by.x = 2, by.y = 0, all.x = TRUE)
    

    这假定如果dat1 中有任何不匹配的行,那么结果中的dat2 列应该用NA 填充,如果dat2 中有不匹配的值,那么它们将被忽略。例如:

    dat2a <- dat2
    rownames(2a)[3] <- "elephant"
    # the above still works:
    merge(dat1, dat2a, by.x = 2, by.y = 0, all.x = TRUE)
    

    以上在 SQL 中称为 left join,可以在 sqldf 中这样完成(忽略警告):

    library(sqldf)
    sqldf("select * 
             from dat1 left join dat2 
             on dat1.variable = dat2.row_names", 
           row.names = TRUE)
    

    【讨论】:

      猜你喜欢
      • 2020-04-10
      • 2019-02-27
      • 2021-07-16
      • 2023-03-16
      • 2016-11-03
      • 2021-07-13
      • 2021-05-27
      • 2017-03-18
      • 1970-01-01
      相关资源
      最近更新 更多