R:根据变量名称中的字符串将数字数据从列旋转到行
R: Pivot numeric data from columns to rows based on string in variable name
我有一个数据集,我想根据变量名称是否包含任何字符串将其转换为长格式:list_a <- c("a", "b", "c" ) 和 list_b <- c("美元"、"欧元"、"英镑")。数据集仅包含一行中的值。我希望 list_b 中的值成为列名,list_a 中的值成为结果数据集中的行名。请参阅下面的可重现示例数据集。
我目前通过应用以下 R 代码(list_b 中的每个值一次)解决这个问题,产生三个数据帧,分别称为“df_usd”、“df_eur”和“df_gbp”,然后我根据“名称”列合并。然而,这有点麻烦,如果你能帮我找到一个更优雅的解决方案,我将不胜感激,因为 list_b 中的变量每个月都在变化(list_a 每个月保持不变)并且手动更新现有代码既费时又容易出现手动错误。
# Current solution for df_usd:
df_usd <- df %>%
select(date, contains("usd")) %>%
pivot_longer(cols = contains(c("a_", "b_", "c_")),
names_to = "name", values_to = "usd") %>% mutate(name = case_when(
str_detect(name, "a_") ~ "a",
str_detect(name, "b_") ~ "b",
str_detect(name, "c_") ~ "c")) %>%
select(-date)
起点截图Excel
我想要在 Excel 中实现的结果的屏幕截图
# Example data to copy and paste into R for easy reproduction of problem:
df <- data.frame (date = c("2020-12-31"),
a_usd = c(1000),
b_usd = c(2000),
c_usd = c(3000),
a_eur = c(100),
b_eur =c(200),
c_eur = c(300),
a_gbp = c(10),
b_gbp = c(20),
c_gbp = c(30))
在pivot_longer
中用names_to
指定names_sep
library(dplyr)
df %>%
pivot_longer(cols = -date, names_to = c("grp", ".value"), names_sep = "_")
-输出
# A tibble: 3 x 5
# date grp usd eur gbp
# <chr> <chr> <dbl> <dbl> <dbl>
#1 2020-12-31 a 1000 100 10
#2 2020-12-31 b 2000 200 20
#3 2020-12-31 c 3000 300 30
使用 reshape
的基础 R 选项
reshape(
setNames(df, gsub("(\w+)_(\w+)", "\2.\1", names(df))),
direction = "long",
varying = -1
)
给予
date time usd eur gbp id
1.a 2020-12-31 a 1000 100 10 1
1.b 2020-12-31 b 2000 200 20 1
1.c 2020-12-31 c 3000 300 30 1
我有一个数据集,我想根据变量名称是否包含任何字符串将其转换为长格式:list_a <- c("a", "b", "c" ) 和 list_b <- c("美元"、"欧元"、"英镑")。数据集仅包含一行中的值。我希望 list_b 中的值成为列名,list_a 中的值成为结果数据集中的行名。请参阅下面的可重现示例数据集。
我目前通过应用以下 R 代码(list_b 中的每个值一次)解决这个问题,产生三个数据帧,分别称为“df_usd”、“df_eur”和“df_gbp”,然后我根据“名称”列合并。然而,这有点麻烦,如果你能帮我找到一个更优雅的解决方案,我将不胜感激,因为 list_b 中的变量每个月都在变化(list_a 每个月保持不变)并且手动更新现有代码既费时又容易出现手动错误。
# Current solution for df_usd:
df_usd <- df %>%
select(date, contains("usd")) %>%
pivot_longer(cols = contains(c("a_", "b_", "c_")),
names_to = "name", values_to = "usd") %>% mutate(name = case_when(
str_detect(name, "a_") ~ "a",
str_detect(name, "b_") ~ "b",
str_detect(name, "c_") ~ "c")) %>%
select(-date)
起点截图Excel
我想要在 Excel 中实现的结果的屏幕截图
# Example data to copy and paste into R for easy reproduction of problem:
df <- data.frame (date = c("2020-12-31"),
a_usd = c(1000),
b_usd = c(2000),
c_usd = c(3000),
a_eur = c(100),
b_eur =c(200),
c_eur = c(300),
a_gbp = c(10),
b_gbp = c(20),
c_gbp = c(30))
在pivot_longer
names_to
指定names_sep
library(dplyr)
df %>%
pivot_longer(cols = -date, names_to = c("grp", ".value"), names_sep = "_")
-输出
# A tibble: 3 x 5
# date grp usd eur gbp
# <chr> <chr> <dbl> <dbl> <dbl>
#1 2020-12-31 a 1000 100 10
#2 2020-12-31 b 2000 200 20
#3 2020-12-31 c 3000 300 30
使用 reshape
reshape(
setNames(df, gsub("(\w+)_(\w+)", "\2.\1", names(df))),
direction = "long",
varying = -1
)
给予
date time usd eur gbp id
1.a 2020-12-31 a 1000 100 10 1
1.b 2020-12-31 b 2000 200 20 1
1.c 2020-12-31 c 3000 300 30 1