R:将函数应用于数据框中的多个命名列 - 改进?

时间:2014-03-19 18:58:16

标签: r dataframe apply

我有一个包含多个列的数据框。我想对许多这些列进行重复操作,我已经用名字标记了这些列。

例如:

convert.f <- function(v) {
  if (is.numeric(v) && !is.factor(v)) {
    v <- as.factor(v)
  }
  return (v)
}
f <- data.frame(X1=rep(2,2),X2=rep(1,2), X3=rep(3,2), XA=rep('a',2), X4=rep(4,2))
cols <- c('X1', 'X2', 'X4')

# Now, I want to apply 'convert.f' to cols X1, X2, and X4 only and store it in the
# original data frame.

以下所有尝试均不正确。

# Doesn't seem to return a data frame I can use...
apply(f[, cols], 2, convert.f)

# Same as above I think
f2 <- sapply(f[, cols], convert.f)

# Even if I coerce it, I get some problems
f2 <- data.frame(f2)
f2$X1 # Error

# Appears to have no change in the data frame
ddply(f, cols, convert.f)

# This doesn't seem to save the results back into the frame
for (col in cols) {
  f[col] <- convert.f(f[col])
}

可能的解决方案:

# Here's the best way I've found so far but it seems inefficient.
f3 <- data.frame(lapply(f[,cols], convert.f))
f[, names(f3)] <- f3

# However, if I do this in a function and return f, it doesn't seem to make my changes stick. Still trying to figure that one out.

为什么最后一个使用lapply强制转换为数据框?

这里有什么改进吗?似乎我错过了一些基本的东西,如何应用各种&#39;功能工作。

1 个答案:

答案 0 :(得分:1)

你最后两次尝试非常接近。这是一个有效的简单版本:

f[cols] <- lapply(f[cols], convert.f)

产生:

'data.frame':   2 obs. of  5 variables:
 $ X1: Factor w/ 1 level "2": 1 1
 $ X2: Factor w/ 1 level "1": 1 1
 $ X3: num  3 3
 $ XA: Factor w/ 1 level "a": 1 1
 $ X4: Factor w/ 1 level "4": 1 1

注意:

for (col in cols) {
  f[col] <- convert.f(f[, col])
}

也有效。您的版本无法正常运行,因为f[col]会返回数据框而不是向量,因此您的is.numeric(v)测试失败,而convert.f会返回插入f[col]的未更改的单列数据框},所以看起来f没有改变。通过使用[的两个参数版本,drop参数启动,f[, col]返回向量而不是1列数据框。