R对特定数据框列的Apply()函数


75

我想在数据框上使用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 

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


2
“ by”呼叫使这个问题变得复杂。如果相关,您应该重写问题以澄清(什么是wifi $ Room?)。我在下面的回答中忽略了。
leif

您可以cbind(y[1:3], ...)得到的结果。
IRTFM

Answers:


59

使用示例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

有没有一种方法可以$通过按名称对某个列[ : ]进行索引,而不是按列号进行索引?我尝试添加姓氏:colnames(wifi) = c("a", "b", "c", "d", "e", "f", "g", "h" ,"i")但是没有尝试使用lapply(wifi $ e,2,X)。
santeko

9
@skotturi-您可以执行此操作,例如wifi[c("a","b","c")]按名称索引多个列。
thelatemail 2015年

@ thelatemail,在apply(wifi[4:9],2, A)wifi[4:9]data.frame。而且apply只能用于数组或matrix.Why你的答案是否可行?
kittygirl,

@kittygirl-这是因为apply可以在data.frame上使用。使用apply时,data.frame将被强制转换为矩阵,作为函数的一部分。
thelatemail '20

@thelatemail,会丢失行名或姓氏信息吗?
kittygirl

88

lapply可能是比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)

2
一个小小的修正:wifi <-data.frame(A = 1:4,B = runif(4),C = 5:8)
jcfaria 2013年

您能否更清楚地了解如何创建[cols]向量?
Mox

@Mox您可以做cols <- c("var1", "var2")
cparmstrong '18

作为使用dplyr的替代方法,避免了重复列规范的冗余,您可以这样做wifi[4:9] %<>% map_dbl(A)
Agile Bean,

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)

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


0

我认为您想要的是mapply。您可以将函数应用于所有列,然后删除不需要的列。但是,如果您要对不同的列应用不同的功能,则似乎您想要的是dplyr包中的mutate

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.