R:从一列中识别非 NA 值,并使用来自另一列的基于所选行的值创建数据框
R: Identify non-NA values from one column and create dataframe with values from another column based rows selected
我有一个包含多列 (45) 和多行 (20,000) 的数据框 (df):
我想通过仅选择具有非 NA 值的行并为所选行创建一个具有相应 ID 和名称的单独数据框来过滤每个变量列。然后我想用相应的变量名保存每个数据框。例如,输出数据帧将如下所示,并分别保存为 Var1 和 Var2。
变量 1 <
变量 2 <
我目前正在尝试在 R 上使用这个函数并考虑实现一个 for 循环。
df2 = lapply(df, 函数(x) {x[!is.na(x)]}).
这并没有很好地工作,因为它没有列出相应 ID 和 Name 列的值。这也不会创建数据框。
如有任何建议,我们将不胜感激!
下面是使用 dplyr
& purrr
的方法
请注意,下次不要发布您的数据图像,请尝试在 R 中创建示例数据并复制粘贴该示例数据的 dput
。
library(purrr)
library(dplyr)
data <- tibble(ID = c("A", "B", "C"),
Name = c("D", "E", "F"),
Var1 = c(1, NA, 2),
Var2 = c(2, 2, NA),
Var4 = c(NA, NA, 4))
columns <- names(data)[grepl("^Var", names(data))]
extract_na_item <- function(column_name, df) {
df %>%
filter(!is.na(!!sym(column_name))) %>%
select(ID, Name)
}
list_var_not_na <- map(columns, extract_na_item, df = data)
names(list_var_not_na) <- columns
这是结果
list_var_not_na
#> $Var1
#> # A tibble: 2 x 2
#> ID Name
#> <chr> <chr>
#> 1 A D
#> 2 C F
#>
#> $Var2
#> # A tibble: 2 x 2
#> ID Name
#> <chr> <chr>
#> 1 A D
#> 2 B E
#>
#> $Var4
#> # A tibble: 1 x 2
#> ID Name
#> <chr> <chr>
#> 1 C F
如果你真的想像你在 OP 中提到的那样在全局环境中进行变量赋值,你可以按照下面的方式进行操作(尽管我建议只使用列表来访问数据)
list2env(list_var_not_na, envir = globalenv())
由 reprex package (v2.0.0)
于 2021-05-03 创建
您可以像这样使用 lapply
:
cols <- grep('Var', names(df))
df2 <- lapply(df[cols], function(x) df[!is.na(x), -cols])
df2
#$Var1
# ID Name
#1 A D
#3 C F
#$Var2
# ID Name
#1 A D
#2 B E
#$Var4
# ID Name
#3 C F
数据
df <- structure(list(ID = c("A", "B", "C"), Name = c("D", "E", "F"),
Var1 = c(1, NA, 2), Var2 = c(2, 2, NA), Var4 = c(NA, NA,
4)), class = "data.frame", row.names = c(NA, -3L))
我有一个包含多列 (45) 和多行 (20,000) 的数据框 (df):
我想通过仅选择具有非 NA 值的行并为所选行创建一个具有相应 ID 和名称的单独数据框来过滤每个变量列。然后我想用相应的变量名保存每个数据框。例如,输出数据帧将如下所示,并分别保存为 Var1 和 Var2。
变量 1 <
变量 2 <
我目前正在尝试在 R 上使用这个函数并考虑实现一个 for 循环。
df2 = lapply(df, 函数(x) {x[!is.na(x)]}).
这并没有很好地工作,因为它没有列出相应 ID 和 Name 列的值。这也不会创建数据框。
如有任何建议,我们将不胜感激!
下面是使用 dplyr
& purrr
请注意,下次不要发布您的数据图像,请尝试在 R 中创建示例数据并复制粘贴该示例数据的 dput
。
library(purrr)
library(dplyr)
data <- tibble(ID = c("A", "B", "C"),
Name = c("D", "E", "F"),
Var1 = c(1, NA, 2),
Var2 = c(2, 2, NA),
Var4 = c(NA, NA, 4))
columns <- names(data)[grepl("^Var", names(data))]
extract_na_item <- function(column_name, df) {
df %>%
filter(!is.na(!!sym(column_name))) %>%
select(ID, Name)
}
list_var_not_na <- map(columns, extract_na_item, df = data)
names(list_var_not_na) <- columns
这是结果
list_var_not_na
#> $Var1
#> # A tibble: 2 x 2
#> ID Name
#> <chr> <chr>
#> 1 A D
#> 2 C F
#>
#> $Var2
#> # A tibble: 2 x 2
#> ID Name
#> <chr> <chr>
#> 1 A D
#> 2 B E
#>
#> $Var4
#> # A tibble: 1 x 2
#> ID Name
#> <chr> <chr>
#> 1 C F
如果你真的想像你在 OP 中提到的那样在全局环境中进行变量赋值,你可以按照下面的方式进行操作(尽管我建议只使用列表来访问数据)
list2env(list_var_not_na, envir = globalenv())
由 reprex package (v2.0.0)
于 2021-05-03 创建您可以像这样使用 lapply
:
cols <- grep('Var', names(df))
df2 <- lapply(df[cols], function(x) df[!is.na(x), -cols])
df2
#$Var1
# ID Name
#1 A D
#3 C F
#$Var2
# ID Name
#1 A D
#2 B E
#$Var4
# ID Name
#3 C F
数据
df <- structure(list(ID = c("A", "B", "C"), Name = c("D", "E", "F"),
Var1 = c(1, NA, 2), Var2 = c(2, 2, NA), Var4 = c(NA, NA,
4)), class = "data.frame", row.names = c(NA, -3L))