R:将任意串联变量名和值的向量转换为单个数据帧
我有一个两列多行的数据框 第一列是一个字符向量,其中每个元素p是一个字符串,该字符串用逗号连接K个字符串。K是事先未知的,可以跨行变化,因此第一行的K=5,第二行的K=3。连接在一起的值在行之间可能相同,也可能不同,尽管它们在一行中不重复。我们可以称这些变量名 第二列——我们可以称之为变量值——是一个字符向量,其中每个元素也是一个字符串,用逗号连接K个字符串。重要的是,连接的字符串数量与变量名的数量相同。换句话说,variable names列包含一个包含变量名称的字符串,variable values列包含与该行的变量名称相对应的值 这是我的数据的一个最小示例。注意,例如var_名称[i]中的子字符串数量等于值[i]中的相同数量,但不必等于var_名称[j]: 我能用下面的工具生产出我想要的东西。然而,我想知道是否有一些函数/包可以让我跳过这些步骤,更快地完成这些步骤。目前,我创建了一个循环,为每一行生成整个数据帧,然后将它们组合成一个数据帧。我最初的想法是在代码中使用var_val对象,并使用tidyr::pivot_更广泛地生成每一行的数据帧,但由于规范错误,这不起作用R:将任意串联变量名和值的向量转换为单个数据帧,r,list,dataframe,dplyr,data-manipulation,R,List,Dataframe,Dplyr,Data Manipulation,我有一个两列多行的数据框 第一列是一个字符向量,其中每个元素p是一个字符串,该字符串用逗号连接K个字符串。K是事先未知的,可以跨行变化,因此第一行的K=5,第二行的K=3。连接在一起的值在行之间可能相同,也可能不同,尽管它们在一行中不重复。我们可以称这些变量名 第二列——我们可以称之为变量值——是一个字符向量,其中每个元素也是一个字符串,用逗号连接K个字符串。重要的是,连接的字符串数量与变量名的数量相同。换句话说,variable names列包含一个包含变量名称的字符串,variable va
# Split variable names and values into a list
# where each element is a row's values/names
vars_name_l <- strsplit(data$var_names, split = ",")
values_l <- strsplit(data$values, split = ",")
# Initialize a list to store each row's
# data frame
combined <- list()
# Loop through each row's data and generate a
# list of data frames
for (i in 1:length(nrow(data))) {
# Get a row's variable names and values into
# a data frame.
var_val <- data.frame(var_names = vars_name_l[[i]],
values = values_l[[i]],
stringsAsFactors = FALSE)
# Create an empty data frame then add variable
# names and the values for the variables, store in
# our list
df <- as.data.frame(matrix(numeric(), nrow = 0, ncol = length(var_val$var_names)))
colnames(df) <- var_val$var_names
df[1, ] <- var_val$values
combined[[i]] <- df
}
# Collapse list to a single data frame, rearrange
result <- bind_rows(combined)
result[ ,order(colnames(result))]
我们可以首先从列var_名称和值中获取单独行中的数据,然后获取宽格式的数据
library(dplyr)
library(tidyr)
data %>%
mutate(row = row_number()) %>%
separate_rows(var_names, values) %>%
pivot_wider(names_from = var_names, values_from = values) %>%
select(-row)
# a b c e j d f k
# <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#1 212 12 sfd 3 1 NA NA NA
#2 23 NA NA NA NA fds g NA
#3 w w2 NA NA NA NA df sdf
我们可以很容易地用bind_行来实现这一点
或者另一种选择是从tidyr开始的
@user3614648对我来说很好。可能是软件包的版本dplyr@user3614648你能试试最新的吗。我正在使用devel versiioin。那么第一个可能会有一些clash@user3614648我看到的主要问题是第一个是命名向量,而第二个是命名列表,命名列表不应该在bind中创建错误_rows@user3614648我又增加了3个选项,希望其中一个对你有用
# Split variable names and values into a list
# where each element is a row's values/names
vars_name_l <- strsplit(data$var_names, split = ",")
values_l <- strsplit(data$values, split = ",")
# Initialize a list to store each row's
# data frame
combined <- list()
# Loop through each row's data and generate a
# list of data frames
for (i in 1:length(nrow(data))) {
# Get a row's variable names and values into
# a data frame.
var_val <- data.frame(var_names = vars_name_l[[i]],
values = values_l[[i]],
stringsAsFactors = FALSE)
# Create an empty data frame then add variable
# names and the values for the variables, store in
# our list
df <- as.data.frame(matrix(numeric(), nrow = 0, ncol = length(var_val$var_names)))
colnames(df) <- var_val$var_names
df[1, ] <- var_val$values
combined[[i]] <- df
}
# Collapse list to a single data frame, rearrange
result <- bind_rows(combined)
result[ ,order(colnames(result))]
library(dplyr)
library(tidyr)
data %>%
mutate(row = row_number()) %>%
separate_rows(var_names, values) %>%
pivot_wider(names_from = var_names, values_from = values) %>%
select(-row)
# a b c e j d f k
# <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#1 212 12 sfd 3 1 NA NA NA
#2 23 NA NA NA NA fds g NA
#3 w w2 NA NA NA NA df sdf
library(dplyr)
bind_rows(do.call(Map, c(f = setNames, lapply(unname(data)[2:1], strsplit, ","))))
# A tibble: 3 x 8
# a b c e j d f k
#* <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#1 212 12 sfd 3 1 <NA> <NA> <NA>
#2 23 <NA> <NA> <NA> <NA> fds g <NA>
#3 w w2 <NA> <NA> <NA> <NA> df sdf
bind_rows(do.call(Map, c(f = function(x, y)
setNames(as.list(x), y), lapply(unname(data)[2:1], strsplit, ","))))
library(tidyr)
library(purrr)
data %>%
mutate_all(strsplit, ",") %>%
transmute(new = map2(values, var_names, ~ set_names(as.list(.x), .y))) %>%
unnest_wider(c(new))
# A tibble: 3 x 8
# a b c e j d f k
# <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#1 212 12 sfd 3 1 <NA> <NA> <NA>
#2 23 <NA> <NA> <NA> <NA> fds g <NA>
#3 w w2 <NA> <NA> <NA> <NA> df sdf
library(data.table)
rbindlist(do.call(Map, c(f = function(x, y)
setNames(as.list(x), y), lapply(unname(data)[2:1], strsplit, ","))),
fill = TRUE)
# a b c e j d f k
#1: 212 12 sfd 3 1 <NA> <NA> <NA>
#2: 23 <NA> <NA> <NA> <NA> fds g <NA>
#3: w w2 <NA> <NA> <NA> <NA> df sdf