如何在数据帧的每一列中有效地将继任者按前任划分
How to efficiently divide successor by predecessor in each column of a dataframe
我有一个 dataframe
myDF
是这样创建的:
a <- 1:4
b <- seq(3, 16, length=4)
myDF <- data.frame(a=a, b=b)
看起来像这样:
a b
1 1 3.000000
2 2 7.333333
3 3 11.666667
4 4 16.000000
现在我想在每一列中划分后续的前驱和后继,将结果添加到现有数据框中,用 NA
替换每列中的一个缺失值并添加新的列名。对于上面的例子,我想要的结果是这样的:
a b amod bmod
1 1 3.000000 NA NA
2 2 7.333333 2.000000 2.444444
3 3 11.666667 1.500000 1.590909
4 4 16.000000 1.333333 1.371429
因此,在 a
列中,2 除以 1,3 除以 2,4 除以 3,结果存储在 amod
.
我现在的做法是这样的:
divStuff <-function(aCol){
newCol <- aCol[2:length(aCol)]/aCol[1:length(aCol) - 1]
newCol <- c(NA, newCol)
return(newCol)
}
newDF <- data.frame(lapply(myDF, divStuff))
names(newDF) <- paste(names(myDF), "mod", sep="")
endDF <- cbind(myDF, newDF)
我编写了一个函数 divStuff
进行除法,然后调用 lapply
将此函数应用于数据框的每一列。
现在我想知道这是否是执行此操作的方法,或者是否有更聪明的方法来执行此类操作,例如避免 cbind
调用或以一种通过自动添加 NA
来避免行 newCol <- c(NA, newCol)
的方式执行 cbind
。我没有找到好的方法,所有解决方案看起来都类似于 this one。
这是一个快速 data.table
版本(使用 devel version on GH)
library(data.table) ## V 1.9.5
setDT(myDF)[, paste0(names(myDF), "mod") := lapply(.SD, function(x) x/shift(x))]
# a b amod bmod
# 1: 1 3.000000 NA NA
# 2: 2 7.333333 2.000000 2.444444
# 3: 3 11.666667 1.500000 1.590909
# 4: 4 16.000000 1.333333 1.371429
或者与 dplyr
类似,尽管您可能想尝试使用列名(这是由于 mutate_each
中的错误(?),当它删除原始列并且不重命名时给定单个函数时的结果)
library(dplyr)
myDF %>%
mutate_each(funs(./lag(.))) %>%
cbind(myDF, .)
# a b a b
# 1 1 3.000000 NA NA
# 2 2 7.333333 2.000000 2.444444
# 3 3 11.666667 1.500000 1.590909
# 4 4 16.000000 1.333333 1.371429
与base R
:
myDF[,paste0(names(myDF), "mod")] <- sapply(myDF, function(x) c(NA, x[-1]/head(x,-1)))
# a b amod bmod
#1 1 3.000000 NA NA
#2 2 7.333333 2.000000 2.444444
#3 3 11.666667 1.500000 1.590909
#4 4 16.000000 1.333333 1.371429
我有一个 dataframe
myDF
是这样创建的:
a <- 1:4
b <- seq(3, 16, length=4)
myDF <- data.frame(a=a, b=b)
看起来像这样:
a b
1 1 3.000000
2 2 7.333333
3 3 11.666667
4 4 16.000000
现在我想在每一列中划分后续的前驱和后继,将结果添加到现有数据框中,用 NA
替换每列中的一个缺失值并添加新的列名。对于上面的例子,我想要的结果是这样的:
a b amod bmod
1 1 3.000000 NA NA
2 2 7.333333 2.000000 2.444444
3 3 11.666667 1.500000 1.590909
4 4 16.000000 1.333333 1.371429
因此,在 a
列中,2 除以 1,3 除以 2,4 除以 3,结果存储在 amod
.
我现在的做法是这样的:
divStuff <-function(aCol){
newCol <- aCol[2:length(aCol)]/aCol[1:length(aCol) - 1]
newCol <- c(NA, newCol)
return(newCol)
}
newDF <- data.frame(lapply(myDF, divStuff))
names(newDF) <- paste(names(myDF), "mod", sep="")
endDF <- cbind(myDF, newDF)
我编写了一个函数 divStuff
进行除法,然后调用 lapply
将此函数应用于数据框的每一列。
现在我想知道这是否是执行此操作的方法,或者是否有更聪明的方法来执行此类操作,例如避免 cbind
调用或以一种通过自动添加 NA
来避免行 newCol <- c(NA, newCol)
的方式执行 cbind
。我没有找到好的方法,所有解决方案看起来都类似于 this one。
这是一个快速 data.table
版本(使用 devel version on GH)
library(data.table) ## V 1.9.5
setDT(myDF)[, paste0(names(myDF), "mod") := lapply(.SD, function(x) x/shift(x))]
# a b amod bmod
# 1: 1 3.000000 NA NA
# 2: 2 7.333333 2.000000 2.444444
# 3: 3 11.666667 1.500000 1.590909
# 4: 4 16.000000 1.333333 1.371429
或者与 dplyr
类似,尽管您可能想尝试使用列名(这是由于 mutate_each
中的错误(?),当它删除原始列并且不重命名时给定单个函数时的结果)
library(dplyr)
myDF %>%
mutate_each(funs(./lag(.))) %>%
cbind(myDF, .)
# a b a b
# 1 1 3.000000 NA NA
# 2 2 7.333333 2.000000 2.444444
# 3 3 11.666667 1.500000 1.590909
# 4 4 16.000000 1.333333 1.371429
与base R
:
myDF[,paste0(names(myDF), "mod")] <- sapply(myDF, function(x) c(NA, x[-1]/head(x,-1)))
# a b amod bmod
#1 1 3.000000 NA NA
#2 2 7.333333 2.000000 2.444444
#3 3 11.666667 1.500000 1.590909
#4 4 16.000000 1.333333 1.371429