【问题标题】:dplyr joins break on labeled columns (haven)dplyr joins break 标记列(避风港)
【发布时间】:2016-05-31 01:43:37
【问题描述】:

如果我使用 haven 读取带有标签的 Stata 或 SAS 数据集,它将(至少在 haven 0.2.0 中)以以下格式读取:

library(dplyr)
df1 <- data_frame(fips = structure(c(1001, 1001, 1001, 1001, 1001),
                                   label = "FIPS (numeric)"),
                  id = structure(letters[1:5], label = "ID"))
df2 <- data_frame(fips = structure(c(1001, 1003, 1005, 1007, 1009),
                                   label = "FIPS (numeric)"),
                  state = structure("AL", label = "State Abbreviation"))

(如有必要,我可以发布一些生成此数据的 Stata 数据,但这应该很容易使用任何标记的 Stata/SAS 数据集进行验证。)

当我尝试使用任何 dplyr 连接函数来连接带标签的列时,我感到非常失望:

df1 %>% inner_join(df2)

返回错误

eval 中的错误(expr,envir,enclos):无法加入列 'fips' x 'fips':由于类型不兼容,无法加入 'fips' x 'fips' (数字/数字)

避免它的唯一方法似乎是删除连接变量上的标签:

df1 %>%
  mutate(fips = `attr<-`(fips, 'label', NULL)) %>% 
  inner_join(df2 %>% mutate(fips = `attr<-`(fips, 'label', NULL)))

这提出了为什么首先要阅读标签的问题。 (连接也消除了df2 中的标签。)

这似乎是havendplyr 交互方式的错误。有没有更好的解决方案?

【问题讨论】:

  • 更准确地说,这不是dplyr 与结构交互的问题吗,因为它可以在不使用haven 的情况下重现?

标签: r dplyr


【解决方案1】:

尝试将列转换为字符串。这似乎有效

df1$fips<-as.character(df1$fips)
df2$fips<-as.character(df2$fips)
df1 %>% inner_join(df2)

inner_join 的帮助页面确实声明:“要加入的变量的字符向量”

【讨论】:

  • by 参数需要是字符向量,但没有说变量必须是字符。
  • 你是对的。更深入地研究一下,似乎有一个属性“FIPS(数字)”附加到 FIPS 列。将此设置为 attr(df1$fips, "label")
【解决方案2】:

当 dplyr 连接一个变量时,该变量是一个数据集中的一个因素,另一个数据集中的一个字符,它会发出警告但完成连接。数字和字符向量不是兼容的类,因此会出错。通过将它们都转换为字符,连接可以正常工作

library(dplyr)
df1 %>% 
  mutate(fips = as.character(fips)) %>%
  inner_join(
    df2 %>%
      mutate(fips = as.character)
    )

【讨论】:

  • 两列都是数字
【解决方案3】:

这个问题在某个时候得到了修复,并且在 dplyr 0.7.4 中有效。我无法找到修复它的确切版本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 2021-07-21
    相关资源
    最近更新 更多