我还在学习 R 并且想知道我是否有一种优雅的方式来操纵下面的 df 来实现 df2。
我不确定它是否应该用于此循环,但基本上对于每个 V(X)_Type(X) 列(不包括代理列),我想从第一行中减去每一行值当 Proxy_Type(X) 达到 99999 时行停止。
这可能听起来令人困惑,所以希望从 df 到所需 df2 的示例将有助于可视化我要问的内容。
Type1 <- c('ABC','DEF','GHI','JKL','MNO','PQR')
V1_Type1 <- c('1','0.5','1','0.2','3','4')
V2_Type1 <- c('2','0.5','1','0.3','3.2','4.1')
V3_Type1 <- c('3','0.6','1','0.4','3.3','4.3')
Proxy_Type1 <- c('0','99999','99999','99999','99999','99999')
Type2 <- c('DEF','GHI','JKL','MNO','PQR','STU')
V1_Type2 <- c('0.5','1','0.2','3','4','4.2')
V2_Type2 <- c('0.5','1','0.3','3.2','4.1','2.2')
V3_Type2 <- c('0.6','1','0.4','3.3','4.3','3')
Proxy_Type2 <- c('0','1.35','99999','99999','99999','99999')
Type3 <- c('GHI','JKL','MNO','PQR','STU','VWX')
V1_Type3 <- c('1','0.2','3','4','4.2','4.1')
V2_Type3 <- c('1','0.3','3.2','4.1','2.2','1.8')
V3_Type3 <- c('1','0.4','3.3','4.3','3','4.2')
Proxy_Type3 <- c('0','2.5','3','99999','99999','99999')
df <- data.frame(Type1,V1_Type1,V2_Type1,V3_Type1,Proxy_Type1,
Type2,V1_Type2,V2_Type2,V3_Type2,Proxy_Type2,
Type3,V1_Type3,V2_Type3,V3_Type3,Proxy_Type3)
To <- c('DEF','GHI','GHI')
From <- c('GHI','JKL','MNO')
V1 <- c('0.5','-0.8','2')
V2 <- c('0.5','-0.7','2.2')
V3 <- c('0.4','-0.6','2.3')
df2 <- data.frame(To,From,V1,V2,V3)
因此在所需的 df2 数据帧中,您可以看到没有 To 和 From“ABC”“DEF”,因为“DEF”代理是 99999,它会立即跳到“DEF”到“GHI”,然后 V1= (1- 0.5), V2=(1-0.5), V3=(1-0.6) 在 GHI 停止,因为 JKL 有 Proxy_Type2 = 99999。移动到 Type3,“GHI”到“JKL” V1=(0.2-1), V2=( 0.3-1),V3=(0.4-1) 然后“GHI”到“MNO”V1=(3-1),V2=(3.2-1),V3=(3.3-1)。该过程将在这里停止,因为 PQR 有 99999.
我有数百个这样的“类型”类型的列,我想在其中生成从 df 到 df2 的这种计算,手动耗时太多,非常感谢您的帮助。
谢谢
理解问题花了一些时间。如果您先tidy数据,解决方案很简单。在这种情况下,这意味着首先将
df
旋转更长的时间,以便 Type
是一个变量而不是每个变量名称的一部分。
假设数据按行号排序(下例中的
idx
),您只需在每个Type
中执行以下操作(使用group_by()
):在第一个Proxy == 99999之前保留行;做你的计算(当前行减去第一行);根据当前行和第一行设置To
和From
;并删除第一行。然后保留列To
,From
,V1
...Vx,给你df2
:
library(dplyr)
library(tidyr)
df %>%
mutate(idx = row_number()) %>%
pivot_longer(-idx) %>%
mutate(
Type = gsub(".*Type(\\d).*", "\\1", name),
name = name %>%
gsub("_Type\\d", "", .) %>%
gsub("^Type\\d+$", "tofrom", .)
) %>%
pivot_wider() %>%
arrange(Type, idx) %>%
group_by(Type) %>%
filter(row_number() < which(Proxy == 99999)[1]) %>%
mutate(
across(matches("V"), \(x) as.numeric(x) - as.numeric(x)[1]),
To = tofrom[1],
From = tofrom
) %>%
filter(row_number() != 1) %>%
ungroup() %>%
select(To, From, matches("V"))
# A tibble: 3 × 5
To From V1 V2 V3
<chr> <chr> <dbl> <dbl> <dbl>
1 DEF GHI 0.5 0.5 0.4
2 GHI JKL -0.8 -0.7 -0.6
3 GHI MNO 2 2.2 2.3