如果一列中的值与变量名称的一部分匹配,则基于多列创建新变量
Create new variables based on multiple columns if value in one column match part of variable name
我对 R 很陌生,所以请保持温柔。
我有一个包含多个列的数据集,这些列重复测量了好几年。
我有 ID 变量,用于标识与这些措施相关的每一行的特定个人。
我还有一个变量,每行包含一年。
所以我的数据看起来像这样
ID
Y2005_N0X
Y2006_N0X
Y2007_N0X
Y2008_N0X
Y2005_N06
Y2006_N06
Y2007_N06
Y2008_N0X
YEAR
1
5
6
7
8
9
94
29
69
2005
2
6
7
8
9
9
39
59
39
2007
等等...
我想创建一个新列,为 ID 1 使用 2005 年的值,为 ID 2 使用 2007 年的值,并将这个新列命名为 prioryear_N0X。
我有几个这样的列,所以我想创建一个命令来根据这些条件生成多个新列,这样我就会得到一个名为 prioryear_N1X、prioryear_N06 的新列,依此类推向前。 ID 列完好无损也很重要。
在此之后,我还想创建名为 thisyear_N0X 的新列等等,这些列采用 YEAR+1 中的值(例如 2004+1=2005)并匹配当前名为 [=44 的变量=]等等。
ID
Y2005_N0X
Y2006_N0X
Y2007_N0X
Y2008_N0X
Y2005_N06
Y2006_N06
Y2007_N06
Y2008_N0X
YEAR
prioryear_N0X
prioryear_N06
thisyear_N0X
thisyear_N06
1
5
6
7
8
9
94
29
69
2005
5
9
6
94
2
6
7
8
9
9
39
59
39
2007
8
59
9
39
建议?
如果我有同样以 R 开头的变量,我该如何使用该命令?
我尝试了以下方法,但收到错误消息。
df %>%
pivot_longer(cols = -c(ID, YEAR), names_to = c("header_year", ".value"), names_pattern = "Y(\d+)_(\w+)", names_transform = list(header_year = as.integer)) %>%
group_by(ID) %>%
mutate(across(starts_with("N", "R"), function(x) { x[YEAR == header_year] }, .names = "prioryear_{.col}"),
across(starts_with("N", "R"), function(x) { x[YEAR + 1 == header_year] }, .names = "thisyear_{.col}")) %>%
pivot_wider(id_cols = c(ID, YEAR, starts_with("prioryear"), starts_with("thisyear")), names_from = header_year, values_from = starts_with("N", "R"))
这是一种使用 tidyverse
的方法。您可以使用 pivot_longer
输入长格式,然后 mutate
根据以“N”开头的列动态创建新列。这包括两个新列,一列 header 年份与 YEAR
列匹配,一列与 YEAR
+ 1 匹配。最后,您可以将数据放入宽格式,这样类似于您的想要 table.
library(tidyverse)
df %>%
pivot_longer(cols = -c(ID, YEAR), names_to = c("header_year", ".value"), names_pattern = "Y(\d+)_(\w+)", names_transform = list(header_year = as.integer)) %>%
group_by(ID) %>%
mutate(across(starts_with("N"), function(x) { x[YEAR == header_year] }, .names = "prioryear_{.col}"),
across(starts_with("N"), function(x) { x[YEAR + 1 == header_year] }, .names = "thisyear_{.col}")) %>%
pivot_wider(id_cols = c(ID, YEAR, starts_with("prioryear"), starts_with("thisyear")), names_from = header_year, values_from = starts_with("N"))
输出
ID YEAR prioryear_N0X prioryear_N06 thisyear_N0X thisyear_N06 N0X_2005 N0X_2006 N0X_2007 N0X_2008 N06_2005 N06_2006 N06_2007 N06_2008
<int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 1 2005 5 9 6 94 5 6 7 8 9 94 29 69
2 2 2007 8 59 9 39 6 7 8 9 9 39 59 39
我想我解决了。我错过了在使用多个匹配项时必须包含 c。
df %>%
pivot_longer(cols = -c(ID, YEAR), names_to = c("header_year", ".value"), names_pattern = "Y(\d+)_(\w+)", names_transform = list(header_year = as.integer)) %>%
group_by(ID) %>%
mutate(across(starts_with(c("N", "R")), function(x) { x[YEAR == header_year] }, .names = "prioryear_{.col}"),
across(starts_with(c("N", "R")), function(x) { x[YEAR + 1 == header_year] }, .names = "thisyear_{.col}")) %>%
pivot_wider(id_cols = c(ID, YEAR, starts_with("prioryear"), starts_with("thisyear")), names_from = header_year, values_from = starts_with(c("N", "R")))
我对 R 很陌生,所以请保持温柔。
我有一个包含多个列的数据集,这些列重复测量了好几年。 我有 ID 变量,用于标识与这些措施相关的每一行的特定个人。
我还有一个变量,每行包含一年。
所以我的数据看起来像这样
ID | Y2005_N0X | Y2006_N0X | Y2007_N0X | Y2008_N0X | Y2005_N06 | Y2006_N06 | Y2007_N06 | Y2008_N0X | YEAR |
---|---|---|---|---|---|---|---|---|---|
1 | 5 | 6 | 7 | 8 | 9 | 94 | 29 | 69 | 2005 |
2 | 6 | 7 | 8 | 9 | 9 | 39 | 59 | 39 | 2007 |
等等...
我想创建一个新列,为 ID 1 使用 2005 年的值,为 ID 2 使用 2007 年的值,并将这个新列命名为 prioryear_N0X。
我有几个这样的列,所以我想创建一个命令来根据这些条件生成多个新列,这样我就会得到一个名为 prioryear_N1X、prioryear_N06 的新列,依此类推向前。 ID 列完好无损也很重要。
在此之后,我还想创建名为 thisyear_N0X 的新列等等,这些列采用 YEAR+1 中的值(例如 2004+1=2005)并匹配当前名为 [=44 的变量=]等等。
ID | Y2005_N0X | Y2006_N0X | Y2007_N0X | Y2008_N0X | Y2005_N06 | Y2006_N06 | Y2007_N06 | Y2008_N0X | YEAR | prioryear_N0X | prioryear_N06 | thisyear_N0X | thisyear_N06 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 5 | 6 | 7 | 8 | 9 | 94 | 29 | 69 | 2005 | 5 | 9 | 6 | 94 |
2 | 6 | 7 | 8 | 9 | 9 | 39 | 59 | 39 | 2007 | 8 | 59 | 9 | 39 |
建议?
如果我有同样以 R 开头的变量,我该如何使用该命令?
我尝试了以下方法,但收到错误消息。
df %>%
pivot_longer(cols = -c(ID, YEAR), names_to = c("header_year", ".value"), names_pattern = "Y(\d+)_(\w+)", names_transform = list(header_year = as.integer)) %>%
group_by(ID) %>%
mutate(across(starts_with("N", "R"), function(x) { x[YEAR == header_year] }, .names = "prioryear_{.col}"),
across(starts_with("N", "R"), function(x) { x[YEAR + 1 == header_year] }, .names = "thisyear_{.col}")) %>%
pivot_wider(id_cols = c(ID, YEAR, starts_with("prioryear"), starts_with("thisyear")), names_from = header_year, values_from = starts_with("N", "R"))
这是一种使用 tidyverse
的方法。您可以使用 pivot_longer
输入长格式,然后 mutate
根据以“N”开头的列动态创建新列。这包括两个新列,一列 header 年份与 YEAR
列匹配,一列与 YEAR
+ 1 匹配。最后,您可以将数据放入宽格式,这样类似于您的想要 table.
library(tidyverse)
df %>%
pivot_longer(cols = -c(ID, YEAR), names_to = c("header_year", ".value"), names_pattern = "Y(\d+)_(\w+)", names_transform = list(header_year = as.integer)) %>%
group_by(ID) %>%
mutate(across(starts_with("N"), function(x) { x[YEAR == header_year] }, .names = "prioryear_{.col}"),
across(starts_with("N"), function(x) { x[YEAR + 1 == header_year] }, .names = "thisyear_{.col}")) %>%
pivot_wider(id_cols = c(ID, YEAR, starts_with("prioryear"), starts_with("thisyear")), names_from = header_year, values_from = starts_with("N"))
输出
ID YEAR prioryear_N0X prioryear_N06 thisyear_N0X thisyear_N06 N0X_2005 N0X_2006 N0X_2007 N0X_2008 N06_2005 N06_2006 N06_2007 N06_2008
<int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 1 2005 5 9 6 94 5 6 7 8 9 94 29 69
2 2 2007 8 59 9 39 6 7 8 9 9 39 59 39
我想我解决了。我错过了在使用多个匹配项时必须包含 c。
df %>%
pivot_longer(cols = -c(ID, YEAR), names_to = c("header_year", ".value"), names_pattern = "Y(\d+)_(\w+)", names_transform = list(header_year = as.integer)) %>%
group_by(ID) %>%
mutate(across(starts_with(c("N", "R")), function(x) { x[YEAR == header_year] }, .names = "prioryear_{.col}"),
across(starts_with(c("N", "R")), function(x) { x[YEAR + 1 == header_year] }, .names = "thisyear_{.col}")) %>%
pivot_wider(id_cols = c(ID, YEAR, starts_with("prioryear"), starts_with("thisyear")), names_from = header_year, values_from = starts_with(c("N", "R")))