【问题标题】:Losing Class information when I use apply in R当我在 R 中使用 apply 时丢失类信息
【发布时间】:2012-04-06 00:15:44
【问题描述】:

当我使用 apply 将数据框的一行传递给函数时,我丢失了该行元素的类信息。他们都变成了“性格”。下面是一个简单的例子。我想在 3 个臭名昭著的年龄上再增加几年。当我尝试添加 2 一个数值时,R 表示“二元运算符的非数值参数”。我该如何避免这种情况?

age = c(20, 30, 50) 
who = c("Larry", "Curly", "Mo") 
df = data.frame(who, age) 
colnames(df) <- c( '_who_', '_age_')
dfunc <- function (er) {

   print(er['_age_'])
   print(er[2])
   print(is.numeric(er[2]))

  print(class(er[2]))
  return (er[2] + 2)
}
a <- apply(df,1, dfunc)

输出如下:

_age_ 
 "20" 
_age_ 
 "20" 
[1] FALSE
[1] "character"
Error in er[2] + 2 : non-numeric argument to binary operator

【问题讨论】:

    标签: r class apply


    【解决方案1】:

    apply 仅适用于矩阵(所有元素都具有相同的类型)。当您在data.frame 上运行它时,它只会首先调用as.matrix

    解决此问题的最简单方法是仅处理数字列:

    # skips the first column
    a <- apply(df[, -1, drop=FALSE],1, dfunc)
    
    # Or in two steps:
    m <- as.matrix(df[, -1, drop=FALSE])
    a <- apply(m,1, dfunc)
    

    需要drop=FALSE 以避免获得单列向量。 -1 表示除第一列之外的所有列,您可以改为显式指定所需的列,例如 df[, c('foo', 'bar')]

    更新

    如果您希望您的函数一次访问一个完整的 data.frame 行,有(至少)两个选项:

    # "loop" over the index and extract a row at a time
    sapply(seq_len(nrow(df)), function(i) dfunc(df[i,]))
    
    # Use split to produce a list where each element is a row
    sapply(split(df, seq_len(nrow(df))), dfunc)
    

    第一个选项可能更适合大型数据帧,因为它不必预先创建巨大的列表结构。

    【讨论】:

    • 在我的应用程序中,我的数据框很大,并且有日期时间和其他列用于更新行中的一项。我希望避免每次调用函数时将值转换为日期时间和加倍的开销。
    • 我发现这在相关上下文中很有用:df[sapply(df, is.numeric)]
    猜你喜欢
    • 2019-12-22
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多