【问题标题】:Column type changes to "unknown" when its values are all the same [closed]当其值都相同时,列类型更改为“未知”[关闭]
【发布时间】:2019-07-25 13:30:29
【问题描述】:

当我创建一个数据框时,每行中具有相同值的列会自动设置为“未知”类型,并且无法更改它。

下面是一个示例,便于您更好地理解:

data <- data.frame(c(1,1,1,1), c(1:4), c(4:1))
colnames(data) <- c("Not Working", "Ok", "Ok")

此类数据框的第一列(“不工作”)填充了相同的值(全为 1)。 运行代码时,您会注意到它的类型为“未知”,而其他类型则自动设置为“数字”。

但是,如果您尝试更改它,则没有任何效果。例如:

data$`Not Working` <- as.numeric(data$`Not Working`)
data$`Not Working` <- as.numeric(as.character(data$`Not Working`))

您会看到使用这两个代码字符串的列类型仍然相同。既不使用括号而不是美元符号来改变任何东西。 每当一列的所有值都相等时,就会发生这种情况。我还尝试先将数据框变成矩阵,然后再变成数据框,或者先将列变成因子(即使对我的特定类型的数据没有意义),然后变成数字,但没有任何效果。

虽然这对于经典的 R 脚本来说不是问题,但当我尝试编织文件时它变得至关重要,返回以下错误:

"Error [...]: replacement has length zero"

经过多次测试,我发现错误是特定于应该是数字的列类型。我已经正确安装了 R markdown 和 Latex,所以应该没什么。

有谁知道为什么会发生这种情况以及是否有解决方法?它看起来像一个错误或其他东西,但我已经尝试将程序更新到最新版本,但没有任何变化。

【问题讨论】:

  • 我无法从您的示例中重现此错误。代码看起来不错。我建议您运行 sessionInfo() 并粘贴结果,运行 str(data) 并向我们展示结果,并准确重现产生错误的代码。
  • 您如何期望具有重复列名的数据框可能工作?像data$Ok 这样的访问将是模棱两可的(显然使用了第一个匹配项;但它们可能会在 dplyr 或其他库中中断)。此外,为了避免悲伤,最好将列名中的空格修改为下划线,并统一名称,例如Ok.1, Ok.2,见make.names()
  • 我也无法重现这一点,str(data) 确认您的数据框的第一列是数字。请注意,将数据框命名为 data 会影响内置 utils::data
  • 您是否真的有任何正当理由想要将第 2 列和第 3 列的重复名称“Ok”?数据框的列名并不是真正的“第零行”,您可以在其中存储您想要的任何内容而不会产生任何后果。除非您有令人信服的理由需要这样做,否则不要这样做。

标签: r dataframe r-markdown knitr column-types


【解决方案1】:

首先,您不应该有两个具有相同名称的列。我建议您使用tibble 创建数据框。

library(tibble)
data <- tibble("Not Working" = c(1,1,1,1), "Ok" = c(1:4), "Oki" = c(4:1))

sapply(data, class) #check the data types

如果您想将列的数据类型更改为特定的数据类型,您可以轻松指定。

data <- tibble("Not Working" = as.character(c(1,1,1,1)), "Ok" = c(1:4), "Oki" = c(4:1))

【讨论】:

  • 您能补充一下为什么推荐 tibble 吗?
  • 它本质上只是一个更现代的数据框架,删除了一些无效部分并添加了新的附加功能,非常易于使用。它不会更改变量名称或类型,也不会进行部分匹配,但它确实会抱怨更多(例如,当变量不存在时)并迫使您尽早面对问题。 Tibbles 还有一个增强的 print() 方法,这使得它们更容易用于包含复杂对象的大型数据集。
  • 抱歉,可能不太清楚,推荐 tibble 是如何解决 OP 的问题的(而且问题似乎还不清楚,无法回答)?
  • 好吧,在这种情况下,当我使用tibble 运行它时,“不工作”列类型被自动设置为数字而不是未知。
  • all( tibble::tibble("Not Working" = c(1,1,1,1), "Ok" = c(1:4), "Oki" = c(4:1)) == data.frame("Not Working" = c(1,1,1,1), "Ok" = c(1:4), "Oki" = c(4:1), check.names = FALSE) ) 会给我们TRUE。在这种情况下,tibble 没有做任何基本 data.frame 可以做的新事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多