【问题标题】:apply treats numbers as charactersapply 将数字视为字符
【发布时间】:2011-03-11 01:13:47
【问题描述】:

我在网上找不到这个问题的解决方案,虽然看起来很简单。 就是这样:

#Construct test dataframe 
tf <- data.frame(1:3,4:6,c("A","A","A")) 

#Try the apply function I'm trying to use
test <- apply(tf,2,function(x) if(is.numeric(x)) mean(x) else unique(x)[1]) 

#Look at the output--all columns treated as character columns...
test

#Look at the format of the original data--the first two columns are integers. 
str(tf) 

一般来说,我想根据行/列包含的数据类型来区分我 apply 在行/列上的哪个函数。

在这里,如果列是数字列,我想要一个简单的mean,如果列是字符列,我想要一个简单的unique 值。如您所见,apply 将所有列视为字符,就像我编写此函数的方式一样。

【问题讨论】:

    标签: r dataframe apply


    【解决方案1】:

    只需编写一个专门的函数并将其放入sapply...不要使用apply(dtf, 2, fun)。此外,你的角色并不像你想象的那么有个性 - 运行 getOption("stringsAsFactors") 并亲自看看。

    sapply(tf, class)
                X1.3             X4.6 c..A....A....A.. 
           "integer"        "integer"         "factor" 
    sapply(tf, storage.mode)
                X1.3             X4.6 c..A....A....A.. 
           "integer"        "integer"        "integer"
    

    编辑

    甚至更好 - 使用lapply:

    fn <- function(x) {
      if(is.numeric(x) & !is.factor(x)) {
        mean(x)
      } else if (is.character(x)) {
        unique(x)[1]
      } else if (is.factor(x)) {
        as.character(x)[1]
      }
    }
    
    dtf <- data.frame(a = 1:3, b = 4:6, c = rep("A", 3), stringsAsFactors = FALSE)
    dtf2 <- data.frame(a = 1:3, b = 4:6, c = rep("A", 3), stringsAsFactors = TRUE)
    
    as.data.frame(lapply(dtf, fn))
      a b c
    1 2 5 A
    as.data.frame(lapply(dtf2, fn))
      a b c
    1 2 5 A 
    

    【讨论】:

    • 这正是答案——谢谢!为所有做出贡献的人干杯:)
    • 我忘了添加stringsToFactors = FALSE,因为c 列的类默认为factor。您可能需要设置options(stringsAsFactors = FALSE),否则,您将获得factor。请注意。
    【解决方案2】:

    我发现 plyr 包中的 numcolwisecatcolwise 函数在这里很有用,这是一个语法简单的解决方案:

    首先让我们为列命名,以避免在聚合时难看的列名:

    tf <- data.frame(a = 1:3,b=4:6, d = c("A","A","A"))
    

    然后你就可以用这个单线得到你想要的结果:

    > cbind(numcolwise(mean)(tf), catcolwise( function(z) unique(z)[1] )(tf))
      a b d
    1 2 5 A
    

    解释:numcolwise(f) 将其参数(在这种情况下 fmean 函数)转换为一个函数,该函数接受一个数据帧并将f 仅应用于数据帧的数字列。同样,catcolwise 将其函数参数转换为仅对分类列进行操作的函数。

    【讨论】:

      【解决方案3】:

      您想使用 lapply() 或 sapply(),而不是 apply()。 data.frame 是一个列表,它 apply 会在做任何事情之前尝试转换为矩阵。由于数据框中至少有一列是字符,因此在形成该矩阵时,每隔一列也会强制转换为字符。

      【讨论】:

      • 没错,矩阵只能保存一种类型的数据:is.atomic(matrix()) 产生TRUE
      猜你喜欢
      • 1970-01-01
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 2016-01-27
      相关资源
      最近更新 更多