91

我想在数据框上使用 apply 函数,但只将该函数应用于最后 5 列。

B<- by(wifi,(wifi$Room),FUN=function(y){apply(y, 2, A)})

这将 A 应用于 y 的所有列

B<- by(wifi,(wifi$Room),FUN=function(y){apply(y[4:9], 2, A)})

这仅将 A 应用于 y 的第 4-9 列,但 B 的总回报从前 3 列中剔除……我仍然想要那些,我只是不想将 A 应用于它们。

wifi[,1:3]+B 

也没有做我期望/想要的。

4

6 回答 6

108

lapply可能是比apply这里更好的选择,因为 apply 首先将您的 data.frame 强制转换为数组,这意味着所有列必须具有相同的类型。根据您的上下文,这可能会产生意想不到的后果。

模式是:

df[cols] <- lapply(df[cols], FUN)

'cols' 向量可以是变量名或索引。我更喜欢尽可能使用名称(它对列重新排序很可靠)。所以在你的情况下,这可能是:

wifi[4:9] <- lapply(wifi[4:9], A)

使用列名的示例:

wifi <- data.frame(A=1:4, B=runif(4), C=5:8)
wifi[c("B", "C")] <- lapply(wifi[c("B", "C")], function(x) -1 * x)
于 2013-08-29T06:36:24.167 回答
67

使用示例 data.frame 和示例函数(仅对所有值 +1)

A <- function(x) x + 1
wifi <- data.frame(replicate(9,1:4))
wifi

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  1  1  1  1  1  1
#2  2  2  2  2  2  2  2  2  2
#3  3  3  3  3  3  3  3  3  3
#4  4  4  4  4  4  4  4  4  4

data.frame(wifi[1:3], apply(wifi[4:9],2, A) )
#or
cbind(wifi[1:3], apply(wifi[4:9],2, A) )

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5

甚至:

data.frame(wifi[1:3], lapply(wifi[4:9], A) )
#or
cbind(wifi[1:3], lapply(wifi[4:9], A) )

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5
于 2013-08-29T05:56:41.877 回答
2

dplyr使用包的across功能可以轻松完成此任务。

借用thelatemail 建议的数据结构:

A <- function(x) x + 1
wifi <- data.frame(replicate(9,1:4))

我们可以通过如下索引指示我们希望将函数应用到的列:

library(dplyr)
wifi %>% 
   mutate(across(4:9, A))
#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5

或按名称:

wifi %>% 
   mutate(across(X4:X9, A))
#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5
于 2022-01-25T14:26:11.527 回答
1

如前所述,您只需要将标准 Rapply函数应用于列 ( MARGIN=2):

wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A)

或者,简而言之:

wifi[,4:9] <- apply(wifi[,4:9], 2, A)

A()这将使用该函数就地更新 4:9 列。现在,让我们假设这na.rm是 的一个参数A(),它可能应该是。我们可以通过na.rm=T从计算中删除 NA 值,如下所示:

wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A, na.rm=T)

您想要传递给自定义函数的任何其他参数也是如此。

于 2018-04-28T20:06:17.087 回答
0

最简单的方法是使用 mutate 函数:

dataFunctionUsed <- data %>% 
  mutate(columnToUseFunctionOn = function(oldColumn ...))
于 2021-11-10T13:25:07.753 回答
-2

我认为你想要的是mapply。您可以将该函数应用于所有列,然后删除不需要的列。但是,如果您将不同的函数应用于不同的列,您可能想要的是mutate,来自 dplyr 包。

于 2018-04-04T21:40:38.440 回答