【问题标题】:R apply conversion to multiple columns of data.frameR将转换应用于data.frame的多列
【发布时间】:2014-03-10 22:29:29
【问题描述】:

我想将 data.frame 中的几列从 chr 转换为数字,我想在一行中完成。这是我想要做的:

items[,2:4] <- as.numeric(sub("\\$","",items[,2:4]))

但我收到一条错误消息:

Warning message:
NAs introduced by coercion

如果我一栏一栏地做,虽然它有效:

items[,2:2] <- as.numeric(sub("\\$","",items[,2:2]))
items[,3:3] <- as.numeric(sub("\\$","",items[,3:3]))
items[,4:4] <- as.numeric(sub("\\$","",items[,4:4]))

我在这里缺少什么?为什么我为多个列指定此命令?这是我不知道的一些奇怪的 R 特质吗?

示例数据:

Name, Cost1,  Cost2,  Cost3,  Cost4
A,    $10.00, $15.50, $13.20, $45.45
B,    $45.23, $34.23, $34.24, $23.34
C,    $23.43, $45.23, $65.23, $34.23
D,    $76.34, $98.34, $90.34, $45.09

【问题讨论】:

    标签: r dataframe type-conversion


    【解决方案1】:

    您的问题是,gsub 将其x 参数转换为character。如果将 listdata.frame 实际上是 list)转换为 character,则发生连线事件:

    as.character(list(a=c("1", "1"), b="1"))
    # "c(\"1\", \"1\")" "1"
    
    # and "c(\"1\", \"1\")" can not convert into a numeric
    as.numeric("c(\"1\", \"1\")")
    # NA
    

    单行解决方案是unlist x 参数:

    items[, 2:5] <- as.numeric(gsub("\\$", "", unlist(items[, 2:5])))
    

    【讨论】:

    • 谢谢!这就是我一直在寻找的。我很困惑为什么 R 不开心。
    【解决方案2】:

    是的,有:apply 是您要查找的命令:

    items<-read.table(text="Name, Cost1,  Cost2,  Cost3,  Cost4
    A,    $10.00, $15.50, $13.20, $45.45
    B,    $45.23, $34.23, $34.24, $23.34
    C,    $23.43, $45.23, $65.23, $34.23
    D,    $76.34, $98.34, $90.34, $45.09", header=TRUE,sep=",")
    
    items[,2:4]<-apply(items[,2:4],2,function(x){as.numeric(gsub("\\$","",x))})
    items
      Name Cost1 Cost2 Cost3   Cost4
    1    A 10.00 15.50 13.20  $45.45
    2    B 45.23 34.23 34.24  $23.34
    3    C 23.43 45.23 65.23  $34.23
    4    D 76.34 98.34 90.34  $45.09
    

    【讨论】:

    • 谢谢!我仍然很好奇为什么 R 不喜欢这个。 as.numeric() 只喜欢向量而不喜欢多个向量。
    • @MatthewCrews:正如我在回答中所写的那样,问题在于gsub 调用中从listcharacter 的转换。
    【解决方案3】:

    更有效的方法是:

    items[-1] <- lapply(items[-1], function(x) as.numeric(gsub("$", "", x, fixed = TRUE)))
    items
    #   Name Cost1 Cost2 Cost3 Cost4
    # 1    A 10.00 15.50 13.20 45.45
    # 2    B 45.23 34.23 34.24 23.34
    # 3    C 23.43 45.23 65.23 34.23
    # 4    D 76.34 98.34 90.34 45.09
    

    到目前为止答案的一些基准

    fun1 <- function() {
      A[-1] <- lapply(A[-1], function(x) as.numeric(gsub("$", "", x, fixed=TRUE)))
      A
    }
    fun2 <- function() {
      A[, 2:ncol(A)] <- as.numeric(gsub("\\$", "", unlist(A[, 2:ncol(A)])))
      A
    }
    fun3 <- function() {
      A[, 2:ncol(A)] <- apply(A[,2:ncol(A)], 2, function(x) { as.numeric(gsub("\\$","",x)) })
      A
    }
    

    这是一些示例数据和处理时间

    set.seed(1)
    A <- data.frame(Name = sample(LETTERS, 10000, TRUE),
                    matrix(paste0("$", sample(99, 10000*100, TRUE)), 
                           ncol = 100))
    system.time(fun1())
    #    user  system elapsed 
    #    0.72    0.00    0.72 
    system.time(fun2())
    #    user  system elapsed 
    #    5.84    0.00    5.85 
    system.time(fun3())
    #    user  system elapsed 
    #    4.14    0.00    4.14 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2020-07-17
      • 2017-11-20
      • 2020-11-22
      • 1970-01-01
      相关资源
      最近更新 更多