R 如何将数据帧转换为嵌套列表
提供以下结构的R 如何将数据帧转换为嵌套列表,r,regex,R,Regex,提供以下结构的data.frame() var1.性别 var1.score.raw var1.score.raw.lower var1.score.raw.upper […] var2.性别 var2.score.raw var2.score.raw.lower var2.score.raw.upper […] 如何将其转换为多维列表,按拆分 样本数据: df稍后我将使用一些可以查看列名中句点的内容(更复杂)来编辑此内容,但是,在不自动化的情况下,您可以创建嵌套列表,如下所示: df <
data.frame()
var1.性别
var1.score.raw
var1.score.raw.lower
var1.score.raw.upper
[…]
var2.性别
var2.score.raw
var2.score.raw.lower
var2.score.raw.upper
[…]
如何将其转换为多维列表,按
拆分
样本数据:
df稍后我将使用一些可以查看列名中句点的内容(更复杂)来编辑此内容,但是,在不自动化的情况下,您可以创建嵌套列表,如下所示:
df <- data.frame('var1.gender' = c(1,1,3,3), 'var1.score.raw' = c(12.3, 12.4, 14.5, 13.2), 'var1.score.raw.lower' = c(11,11,13,12), 'var1.score.raw.upper' = c(13,13,15,14), 'var2.gender' = c(1,1,3,3), 'var2.score.raw' = c(12.3, 12.4, 14.5, 13.2), 'var2.score.raw.lower' = c(11,11,13,12), 'var2.score.raw.upper' = c(13,13,15,14))
df
# changed your naming here to remove the not-needed ".raw."
colnames(df) <- c("var1.gender", "var1.score.raw", "var1.score.lower", "var1.score.upper", "var2.gender", "var2.score.raw", "var2.score.lower", "var2.score.upper")
nested <- with(df, expr = {list(var1 = list(gender = var1.gender,
score = list(raw = var1.score.raw,
lower = var1.score.lower,
upper = var1.score.upper)),
var2 = list(gender = var2.gender,
score = list(raw = var2.score.raw,
lower = var2.score.lower,
upper = var2.score.upper)))})
nested
$var1
$var1$gender
[1] 1 1 3 3
$var1$score
$var1$score$raw
[1] 12.3 12.4 14.5 13.2
$var1$score$lower
[1] 11 11 13 12
$var1$score$upper
[1] 13 13 15 14
$var2
$var2$gender
[1] 1 1 3 3
$var2$score
$var2$score$raw
[1] 12.3 12.4 14.5 13.2
$var2$score$lower
[1] 11 11 13 12
$var2$score$upper
[1] 13 13 15 14
df通过构造“df”的方式,构建通缉名单的一种简单方法是为“df”的每一列评估一个调用,如list[[“X”][[“Y”]][[“Z”][…]=df$X.Y.Z.
。这可以通过操纵“语言”对象动态完成
定义一个接受列表、名称/索引的字符向量和在该级别分配的值的函数,我们有:
assign_list_element = function(x, inds, val)
{
cl = bquote(x[[.(inds[1])]])
for(s in inds[-1]) cl = bquote(.(cl)[[.(s)]])
cl = call("<-", cl, bquote(.(val)))
print(cl); flush.console()
eval(cl)
return(x)
}
使用这种方法,列表在每次迭代时都会重新构造,尽管它的元素不会被复制。请提供我不清楚所需的输出是什么。你所说的“多维列表”到底是什么意思?你的输出抛出df$var1.score?首先,你提供的df有一个.raw.lower,但你不想再被raw分割,只需要分数。你确定要按时间段具体划分吗?这很好,除了bquote阅读之外,+1,你有没有推荐一些阅读材料让我熟悉R编程的黑暗面?@EvanFriedland:在同样的背景下,你可以看一下和一般的“惰性评估”概念。
nester <- function(df, splitby = "."){
separated <- strsplit(colnames(df), paste0("[", splitby, "]"))
# in order to rbind this into a matrix, we have to make all vectors the same length
n <- max(rapply(separated, length))
separated <- do.call(rbind, rapply(separated, function(x) {length(x) <- n; x }, how = "replace"))
separated <- ifelse(is.na(separated), "empty", separated)
listnames <- apply(separated, 2, unique)
L <- list()
# Assumes n is 3.
for(L1 in listnames[[1]]){
L[[L1]] <- list() # create List level 1
for(L2 in listnames[[2]]){
L[[L1]][[L2]] <- list() # create List level 2
for(L3 in listnames[[3]]){
L[[L1]][[L2]][[L3]] <- list() # create list level 3
# If no data exists for that list combination ...
if(length(df[,which(separated[,1] == L1 & separated[,2] == L2 & separated[,3] == L3)]) == 0){
L[[L1]][[L2]][[L3]] <- NULL # then remove that nested list.
} else {
# otherwise go ahead and put that column in as a list
L[[L1]][[L2]][[L3]] <- df[,which(separated[,1] == L1 & separated[,2] == L2 & separated[,3] == L3)]
# if data is sitting in a list$empty ...
if( L3 == "empty" ){
z <- unname(unlist(L[[L1]][[L2]][[L3]]))
L[[L1]][[L2]][[L3]] <- as.vector(z) # save the empty L3 to the L2
#L[[L1]][[L2]][[L3]] <- NULL # and delete the L3
}
}
}
}
}
return(L)
}
df.List <- nester(df, splitby = ".")
df.List
assign_list_element = function(x, inds, val)
{
cl = bquote(x[[.(inds[1])]])
for(s in inds[-1]) cl = bquote(.(cl)[[.(s)]])
cl = call("<-", cl, bquote(.(val)))
print(cl); flush.console()
eval(cl)
return(x)
}
nms = strsplit(names(df), ".", TRUE)
l = list()
for(i in seq_along(nms)) l = assign_list_element(l, nms[[i]], df[[i]])
#x[["var1"]][["gender"]] <- c(1, 1, 3, 3)
#x[["var1"]][["score"]][["raw"]] <- c(12.3, 12.4, 14.5, 13.2)
#x[["var1"]][["score"]][["lower"]] <- c(11, 11, 13, 12)
#x[["var1"]][["score"]][["upper"]] <- c(13, 13, 15, 14)
#x[["var2"]][["gender"]] <- c(1, 1, 3, 3)
#x[["var2"]][["score"]][["raw"]] <- c(12.3, 12.4, 14.5, 13.2)
#x[["var2"]][["score"]][["lower"]] <- c(11, 11, 13, 12)
#x[["var2"]][["score"]][["upper"]] <- c(13, 13, 15, 14)
str(l)
#List of 2
# $ var1:List of 2
# ..$ gender: num [1:4] 1 1 3 3
# ..$ score :List of 3
# .. ..$ raw : num [1:4] 12.3 12.4 14.5 13.2
# .. ..$ lower: num [1:4] 11 11 13 12
# .. ..$ upper: num [1:4] 13 13 15 14
# $ var2:List of 2
# ..$ gender: num [1:4] 1 1 3 3
# ..$ score :List of 3
# .. ..$ raw : num [1:4] 12.3 12.4 14.5 13.2
# .. ..$ lower: num [1:4] 11 11 13 12
# .. ..$ upper: num [1:4] 13 13 15 14