当我在R中申请时丢失课程信息

时间:2012-04-06 00:15:44

标签: r class apply

当我使用apply将一行数据帧传递给一个函数时,我丢失了该行元素的类信息。他们都变成了'#39;字符'。以下是一个简单的例子。我想给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

1 个答案:

答案 0 :(得分:8)

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)

对于大型数据框,第一个选项可能更好,因为它不必预先创建庞大的列表结构。