【问题标题】:R: Convert text (character) into integer type in a data frameR:将文本(字符)转换为数据框中的整数类型
【发布时间】:2016-08-02 16:38:50
【问题描述】:

我现在正在处理输入数据框:

Asset   Sector        Currency    MarketValue
 1       Financial       USD         100000
 2       Financial       USD         100000
...
100      Financial       USD         100000

虽然现在我想在数据框中添加一行但具有不同的扇区:

101       Energy         USD         100000

我现在正在尝试代码:

newSector        <- rep(input[95,])
newSector$Sector <- "Energy"
input            <- rbind(input,newSector)

但是,从read.csv2() 开始,扇区列被读取为整数类型,而newSector$Sector &lt;- "Energy" 只是将单元格更改为字符类型“能量”,因此我无法将rbind 它们放在一起。 R 报告错误:“无效因子级别,NA 生成”。

我尝试执行 strtoias.integer 但它报告“强制引入的 NA”。

有人可以帮忙吗?非常感谢!

【问题讨论】:

  • 您以不正确的方式引入新关卡。先试试levels(input$Sector) = c(levels(input$Sector), "Energy")。你确定你甚至需要这里的因素吗?
  • 嗨皮埃尔,谢谢你告诉我这个方法。它适用于rbind 新行,但后来我发现我不应该只对新行执行rep,因为它保留了“财务”的值,而只是将名称更改为“能源”,这将不匹配我稍后使用“财务”和“能源”的相关矩阵的计算。我使用了@Uwe Block 的方法,它让我得到了我想要的结果。谢谢!

标签: r text dataframe integer read.csv


【解决方案1】:

在我看来,read.csv() 将 Sector 列作为一个因素而不是整数(或字符串,这是您所期望的)读取。 R 将因子存储为整数,这就是您收到 invalid factor level, NA generated 错误的原因。

您可以通过str(input) 并查看每一列的类来确认这一点。

几个可能的解决方案:

  1. 当您使用 read.csv() 读取原始文件时,请使用 stringsAsFactors=F 参数。这样,Sector 列出现在一个字符列中,您不会感到困惑(如果您需要进行分析,您可以随时将 Sector 转换回一个因子。

  2. 将现有的 input$Sector 转换为字符列:

    input$Sector  <- as.character(input$Sector)
    

【讨论】:

    【解决方案2】:

    假设您的数据名为df,您可以尝试以这种方式添加行:

    df[101,] <- c(101, "Energy", "USD", 100000)
    

    向量包含字符和数值,但由于 R 不能有多个类的向量,它默认为字符。添加此字符向量会将所有 4 列转换为字符。您可以使用lapply 将列更改为整数:

    df[c(1,4)] <- lapply(df[c(1,4)], as.integer)
    

    编辑:如果第二列是一个因子并且添加的值不是本示例中的级别之一,则此方法将不起作用:

    df <- data.frame(
      Asset=1:5,
      Sector=rep("Financial", 5),
      Currency=rep("USD",5),
      MarketValue=rep(100000,5)
    )
    
    > df[6,] <- c(101, "Energy", "USD", 100000)
    Warning message:
    In `[<-.factor`(`*tmp*`, iseq, value = "Energy") :
      invalid factor level, NA generated
    > df
      Asset    Sector Currency MarketValue
    1     1 Financial      USD       1e+05
    2     2 Financial      USD       1e+05
    3     3 Financial      USD       1e+05
    4     4 Financial      USD       1e+05
    5     5 Financial      USD       1e+05
    6   101      <NA>      USD       1e+05
    

    如果将Sector 转换为character,这将起作用

    > df$Sector <- as.character(df$Sector)
    > 
    > df[6,] <- c(101, "Energy", "USD", 100000)
    > df
      Asset    Sector Currency MarketValue
    1     1 Financial      USD       1e+05
    2     2 Financial      USD       1e+05
    3     3 Financial      USD       1e+05
    4     4 Financial      USD       1e+05
    5     5 Financial      USD       1e+05
    6   101    Energy      USD       1e+05
    

    注意类:

    > sapply(df, class)
          Asset      Sector    Currency MarketValue 
    "character" "character"    "factor" "character"
    

    现在lapply

    > df[c(1,4)] <- lapply(df[c(1,4)], as.integer)
    > sapply(df, class)
          Asset      Sector    Currency MarketValue 
      "integer" "character"    "factor"   "integer" 
    

    除非您对数据中的因素有特殊需求,否则我建议您在 read.csv 时使用 stringsAsFactors = FALSE,如其他答案所述。

    【讨论】:

    • 你测试过这个吗?您不能以这种方式逃避因子级别定义。
    【解决方案3】:

    默认情况下,read.csv2 隐含参数stringsAsFactors = TRUE。因此,Sector 列和所有其他字符数据被强制转换为因子,其中因子水平由整数给出。

    请尝试使用stringsAsFactors = FALSE 再次读取输入文件。

    要附加一个额外的扇区,请尝试一下

    newsector <- data.frame(Asset = 101, Sector = "Energy", 
                            Currency = "USD", MarketValue = 100000, 
                            stringsAsFactors = FALSE)
    input <- rbind(input, newSector)
    

    注意这里再次需要参数stringsAsFactors = FALSE,以防止强制因子。

    【讨论】:

    • 谢谢你!我没有更改read.csv2 设置,因为在其他文件中人们也在使用它。我设置了newsector &lt;- data.frame(,stringsAsFactors = TRUE),它很好地得到了我的最终结果。感谢您的帮助!
    猜你喜欢
    • 2022-12-19
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    相关资源
    最近更新 更多