遍历数据框进行计算
Posted
技术标签:
【中文标题】遍历数据框进行计算【英文标题】:Iterate over data frame for calculation 【发布时间】:2022-01-12 21:04:47 【问题描述】:我有一个包含两行的数据框,分别代表上车和下车的乘客:
A B C D E F
In 9 10 6 9 14 10
Out 0 1 2 3 4 3
并且我想做一个计算,将产生另外两行信息,其中第一行是到达车站 A/B/C/等时在公共汽车上的乘客,第 2 行是在那个车站下车的乘客。
第 1 行的数字应该与第 2 行的前一个数字相同,例如 B 站的第 2 行是 `9(从上一站出发的公交车上的剩余人数)+ BIn (在车站上车的人数)- BOut(在车站下车的人数)。
最终结果应该是这样的:
A B C D E F
In 9 10 6 9 14 10
Out 0 1 2 3 4 3
1 0 9 18 22 28 38
2 9 18 22 28 38 45
我将如何遍历数据框以便获得这些数字?是否需要一个 for 循环,或者有没有更简单的方法来完成这个计算?
【问题讨论】:
【参考方案1】:首先,我认为将它们作为列而不是行更有意义。这样您就可以利用 R 中的矢量化操作。
library(data.table)
df <- suppressWarnings(fread('
A B C D E F
In 9 10 6 9 14 10
Out 0 1 2 3 4 3'))
setDT(df) # only required if not starting with a data.table
df
#> V1 A B C D E F
#> <char> <int> <int> <int> <int> <int> <int>
#> 1: In 9 10 6 9 14 10
#> 2: Out 0 1 2 3 4 3
df_tp <- transpose(df, make.names = 'V1', keep.names = 'station')
df_tp
#> station In Out
#> <char> <int> <int>
#> 1: A 9 0
#> 2: B 10 1
#> 3: C 6 2
#> 4: D 9 3
#> 5: E 14 4
#> 6: F 10 3
现在您的最后一行是 In 的累积总和减去 Out 的累积总和。另一个只是它的滞后版本。
df_tp[, net := cumsum(In) - cumsum(Out)]
df_tp[, lagged_net := shift(net, fill = 0)]
df_tp
#> station In Out net lagged_net
#> <char> <int> <int> <int> <int>
#> 1: A 9 0 9 0
#> 2: B 10 1 18 9
#> 3: C 6 2 22 18
#> 4: D 9 3 28 22
#> 5: E 14 4 38 28
#> 6: F 10 3 45 38
由reprex package 创建于 2021-12-07 (v2.0.1)
【讨论】:
谢谢!我对向量运算不是太熟悉,所以我肯定要搜索其中的一些函数。【参考方案2】:我认为您应该接受@IceCreamToucan 的建议和回答,但如果您出于特定原因想要保持相同的结构,这个不优雅的蛮力for
循环将产生您想要的输出:
df <- data.frame(A = c(9,0),
B = c(10,1),
C = c(6,2),
D = c(9,3),
E = c(14, 4),
F = c(10, 3))
for (i in 1:ncol(df))
if (i == 1)df[3:4,1] <- c(0,df[1,1])
else
df[3,i] <- df[4,i-1]
df[4,i] <- sum(df[4,i-1], df[1,i]) - df[2,i]
df
# A B C D E F
#1 9 10 6 9 14 10
#2 0 1 2 3 4 3
#3 0 9 18 22 28 38
#4 9 18 22 28 38 45
【讨论】:
谢谢!我会看看@IceCreamToucan 的答案(我是向量操作的新手),但如果我想使用 for 循环,这就是我正在寻找的 如何为数据框列表执行此操作? 将for
循环定义为function
(即loopfun <- function(x) ...code here...
,然后使用lapply
,类似于lapply(df.lists, loopfun)
【参考方案3】:
或者使用tidyverse
的方式来做到这一点:
以您共享的格式加载数据:
library(tidyverse)
df <- data.frame(A = c(9,0),
B = c(10,1),
C = c(6,2),
D = c(9,3),
E = c(14,4),
F = c(10,3))
> df
A B C D E F
1 9 10 6 9 14 10
2 0 1 2 3 4 3
转换为长格式:
df <- as_tibble(t(df), rownames = "row_names") %>%
rename('In' = V1, 'Out' = V2)
> df
# A tibble: 6 x 3
row_names In Out
<chr> <dbl> <dbl>
1 A 9 0
2 B 10 1
3 C 6 2
4 D 9 3
5 E 14 4
6 F 10 3
用cumsum
和lag
添加你想要的变量:
df %>% mutate(net = cumsum(In) - cumsum(Out),
lag = replace_na(lag(net), 0))
> df
# A tibble: 6 x 5
row_names In Out net lag
<chr> <dbl> <dbl> <dbl> <dbl>
1 A 9 0 9 0
2 B 10 1 18 9
3 C 6 2 22 18
4 D 9 3 28 22
5 E 14 4 38 28
6 F 10 3 45 38
【讨论】:
以上是关于遍历数据框进行计算的主要内容,如果未能解决你的问题,请参考以下文章