在 for 循环中使用 diff 函数
Using the diff function in a for loop
我有一个数据框,我想生成列,这些列在它之前的列之间存在差异。即有一个包含第 1 列 - 第 2 列的新列,接下来是第 2 列 - 第 3 列,等等。我已经写出代码(~伪代码?)但我不完全确定如何正确格式化它。这将成为不同文档的管道,因此我无法对列名或编号进行硬编码。我还希望此循环生成一个新列,其中 header 具有它减去的列的名称。
我的数据:
Line_1 Line_2 Line_3 Line_4 Line_5 Line_6 Line_7
1 NA NA NA NA NA 0.0000000 NA
2 0.4054731 0.3193632 0.2667026 0.8494675 0.2394639 0.2936054 0.2453124
3 0.4048527 0.3195507 0.2693250 0.8664931 0.2380499 0.2931895 0.2437657
4 0.4041760 0.3226145 0.2731347 0.8756971 0.2338797 0.2876017 0.2432391
5 0.4079322 0.3264623 0.2750645 0.8770746 0.2273580 0.2866682 0.2476563
我的“代码”:
for (n in 1:ncol(tempDF2)) {
sub <- diff(n, lag = 1, differences = 1)
name <- paste0(n, " - ", n+1)
tempDF2$name <- sub
}
我怎样才能让它工作?我也愿意申请 sapply 等循环的替代方案。
您可以使用 matrixStats
包中的 rowDiffs
并反转差异:
library(matrixStats)
df <- structure(list(Line_1 = c(NA, 0.4054731, 0.4048527, 0.404176,
0.4079322), Line_2 = c(NA, 0.3193632, 0.3195507, 0.3226145, 0.3264623
), Line_3 = c(NA, 0.2667026, 0.269325, 0.2731347, 0.2750645),
Line_4 = c(NA, 0.8494675, 0.8664931, 0.8756971, 0.8770746
), Line_5 = c(NA, 0.2394639, 0.2380499, 0.2338797, 0.227358
), Line_6 = c(NA, 0.2936054, 0.2931895, 0.2876017, 0.2866682
), Line_7 = c(0, 0.2453124, 0.2437657, 0.2432391, 0.2476563
)), class = "data.frame", row.names = c(NA, -5L))
-rowDiffs(as.matrix(df))
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] NA NA NA NA NA NA
#> [2,] 0.0861099 0.0526606 -0.5827649 0.6100036 -0.0541415 0.0482930
#> [3,] 0.0853020 0.0502257 -0.5971681 0.6284432 -0.0551396 0.0494238
#> [4,] 0.0815615 0.0494798 -0.6025624 0.6418174 -0.0537220 0.0443626
#> [5,] 0.0814699 0.0513978 -0.6020101 0.6497166 -0.0593102 0.0390119
编辑:
如果与您的问题相反,您想要 Line_2 - Line_1 等的差异,那么它将是:
setNames(data.frame(rowDiffs(as.matrix(df))),
paste0(colnames(df)[-1], "-", colnames(df)[-ncol(df)]))
#> Line_2-Line_1 Line_3-Line_2 Line_4-Line_3 Line_5-Line_4 Line_6-Line_5
#> 1 NA NA NA NA NA
#> 2 -0.0861099 -0.0526606 0.5827649 -0.6100036 0.0541415
#> 3 -0.0853020 -0.0502257 0.5971681 -0.6284432 0.0551396
#> 4 -0.0815615 -0.0494798 0.6025624 -0.6418174 0.0537220
#> 5 -0.0814699 -0.0513978 0.6020101 -0.6497166 0.0593102
#> Line_7-Line_6
#> 1 NA
#> 2 -0.0482930
#> 3 -0.0494238
#> 4 -0.0443626
#> 5 -0.0390119
由 reprex package (v0.3.0)
于 2020-07-01 创建
不确定这是否正是您要查找的内容,但以下函数将按顺序计算第 1 列与第 n 列之间的差异。这显然只适用于具有数字列的数据框。您可以使用 dplyr
和动态变量命名(即 enquo()
)获得更多乐趣,但这可能会让您朝着正确的方向前进。
diff_cols <- function(dat) {
list <- names(dat)
col <- list()
nam <- vector()
for(i in 1:(ncol(dat)-1)) {
col[[i]] <- dat[,i]-dat[,i+1]
nam[i] <- paste0(list[i], "-" ,list[i+1])
}
df <- as.data.frame(do.call(cbind, col))
colnames(df) <- nam
return(df)
}
dat <- select_if(iris, is.numeric)
diff_cols(dat)
在 base R
中,我们可以通过取相同大小 data.frames 的差值(通过删除第一列和最后一列)
out <- tempDF2[-ncol(tempDF2)] - tempDF2[-1]
names(out) <- paste0(names(tempDF2)[-1], "-", names(tempDF2)[-ncol(tempDF2)])
out
# Line_2-Line_1 Line_3-Line_2 Line_4-Line_3 Line_5-Line_4 Line_6-Line_5 Line_7-Line_6
#1 NA NA NA NA NA NA
#2 0.0861099 0.0526606 -0.5827649 0.6100036 -0.0541415 0.0482930
#3 0.0853020 0.0502257 -0.5971681 0.6284432 -0.0551396 0.0494238
#4 0.0815615 0.0494798 -0.6025624 0.6418174 -0.0537220 0.0443626
#5 0.0814699 0.0513978 -0.6020101 0.6497166 -0.0593102 0.0390119
数据
tempDF2 <- structure(list(Line_1 = c(NA, 0.4054731, 0.4048527, 0.404176,
0.4079322), Line_2 = c(NA, 0.3193632, 0.3195507, 0.3226145, 0.3264623
), Line_3 = c(NA, 0.2667026, 0.269325, 0.2731347, 0.2750645),
Line_4 = c(NA, 0.8494675, 0.8664931, 0.8756971, 0.8770746
), Line_5 = c(NA, 0.2394639, 0.2380499, 0.2338797, 0.227358
), Line_6 = c(NA, 0.2936054, 0.2931895, 0.2876017, 0.2866682
), Line_7 = c(0, 0.2453124, 0.2437657, 0.2432391, 0.2476563
)), class = "data.frame", row.names = c(NA, -5L))
我有一个数据框,我想生成列,这些列在它之前的列之间存在差异。即有一个包含第 1 列 - 第 2 列的新列,接下来是第 2 列 - 第 3 列,等等。我已经写出代码(~伪代码?)但我不完全确定如何正确格式化它。这将成为不同文档的管道,因此我无法对列名或编号进行硬编码。我还希望此循环生成一个新列,其中 header 具有它减去的列的名称。
我的数据:
Line_1 Line_2 Line_3 Line_4 Line_5 Line_6 Line_7
1 NA NA NA NA NA 0.0000000 NA
2 0.4054731 0.3193632 0.2667026 0.8494675 0.2394639 0.2936054 0.2453124
3 0.4048527 0.3195507 0.2693250 0.8664931 0.2380499 0.2931895 0.2437657
4 0.4041760 0.3226145 0.2731347 0.8756971 0.2338797 0.2876017 0.2432391
5 0.4079322 0.3264623 0.2750645 0.8770746 0.2273580 0.2866682 0.2476563
我的“代码”:
for (n in 1:ncol(tempDF2)) {
sub <- diff(n, lag = 1, differences = 1)
name <- paste0(n, " - ", n+1)
tempDF2$name <- sub
}
我怎样才能让它工作?我也愿意申请 sapply 等循环的替代方案。
您可以使用 matrixStats
包中的 rowDiffs
并反转差异:
library(matrixStats)
df <- structure(list(Line_1 = c(NA, 0.4054731, 0.4048527, 0.404176,
0.4079322), Line_2 = c(NA, 0.3193632, 0.3195507, 0.3226145, 0.3264623
), Line_3 = c(NA, 0.2667026, 0.269325, 0.2731347, 0.2750645),
Line_4 = c(NA, 0.8494675, 0.8664931, 0.8756971, 0.8770746
), Line_5 = c(NA, 0.2394639, 0.2380499, 0.2338797, 0.227358
), Line_6 = c(NA, 0.2936054, 0.2931895, 0.2876017, 0.2866682
), Line_7 = c(0, 0.2453124, 0.2437657, 0.2432391, 0.2476563
)), class = "data.frame", row.names = c(NA, -5L))
-rowDiffs(as.matrix(df))
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] NA NA NA NA NA NA
#> [2,] 0.0861099 0.0526606 -0.5827649 0.6100036 -0.0541415 0.0482930
#> [3,] 0.0853020 0.0502257 -0.5971681 0.6284432 -0.0551396 0.0494238
#> [4,] 0.0815615 0.0494798 -0.6025624 0.6418174 -0.0537220 0.0443626
#> [5,] 0.0814699 0.0513978 -0.6020101 0.6497166 -0.0593102 0.0390119
编辑:
如果与您的问题相反,您想要 Line_2 - Line_1 等的差异,那么它将是:
setNames(data.frame(rowDiffs(as.matrix(df))),
paste0(colnames(df)[-1], "-", colnames(df)[-ncol(df)]))
#> Line_2-Line_1 Line_3-Line_2 Line_4-Line_3 Line_5-Line_4 Line_6-Line_5
#> 1 NA NA NA NA NA
#> 2 -0.0861099 -0.0526606 0.5827649 -0.6100036 0.0541415
#> 3 -0.0853020 -0.0502257 0.5971681 -0.6284432 0.0551396
#> 4 -0.0815615 -0.0494798 0.6025624 -0.6418174 0.0537220
#> 5 -0.0814699 -0.0513978 0.6020101 -0.6497166 0.0593102
#> Line_7-Line_6
#> 1 NA
#> 2 -0.0482930
#> 3 -0.0494238
#> 4 -0.0443626
#> 5 -0.0390119
由 reprex package (v0.3.0)
于 2020-07-01 创建不确定这是否正是您要查找的内容,但以下函数将按顺序计算第 1 列与第 n 列之间的差异。这显然只适用于具有数字列的数据框。您可以使用 dplyr
和动态变量命名(即 enquo()
)获得更多乐趣,但这可能会让您朝着正确的方向前进。
diff_cols <- function(dat) {
list <- names(dat)
col <- list()
nam <- vector()
for(i in 1:(ncol(dat)-1)) {
col[[i]] <- dat[,i]-dat[,i+1]
nam[i] <- paste0(list[i], "-" ,list[i+1])
}
df <- as.data.frame(do.call(cbind, col))
colnames(df) <- nam
return(df)
}
dat <- select_if(iris, is.numeric)
diff_cols(dat)
在 base R
中,我们可以通过取相同大小 data.frames 的差值(通过删除第一列和最后一列)
out <- tempDF2[-ncol(tempDF2)] - tempDF2[-1]
names(out) <- paste0(names(tempDF2)[-1], "-", names(tempDF2)[-ncol(tempDF2)])
out
# Line_2-Line_1 Line_3-Line_2 Line_4-Line_3 Line_5-Line_4 Line_6-Line_5 Line_7-Line_6
#1 NA NA NA NA NA NA
#2 0.0861099 0.0526606 -0.5827649 0.6100036 -0.0541415 0.0482930
#3 0.0853020 0.0502257 -0.5971681 0.6284432 -0.0551396 0.0494238
#4 0.0815615 0.0494798 -0.6025624 0.6418174 -0.0537220 0.0443626
#5 0.0814699 0.0513978 -0.6020101 0.6497166 -0.0593102 0.0390119
数据
tempDF2 <- structure(list(Line_1 = c(NA, 0.4054731, 0.4048527, 0.404176,
0.4079322), Line_2 = c(NA, 0.3193632, 0.3195507, 0.3226145, 0.3264623
), Line_3 = c(NA, 0.2667026, 0.269325, 0.2731347, 0.2750645),
Line_4 = c(NA, 0.8494675, 0.8664931, 0.8756971, 0.8770746
), Line_5 = c(NA, 0.2394639, 0.2380499, 0.2338797, 0.227358
), Line_6 = c(NA, 0.2936054, 0.2931895, 0.2876017, 0.2866682
), Line_7 = c(0, 0.2453124, 0.2437657, 0.2432391, 0.2476563
)), class = "data.frame", row.names = c(NA, -5L))