提问人:Divs 提问时间:8/20/2022 最后编辑:Divs 更新时间:8/23/2022 访问量:283
R 更改嵌套列表的类型
R Change type of nested list
问:
更新: 我有一个嵌套列表,我正在尝试将嵌套列表最深层次的类更改为数据框。我不想在数据框中使用更高级别。我也有我尝试在子列表 1 和 C 下的列表中作为字符向量的内容。我希望 C 是一个字符向量,但是当我对它执行 typeof() 或 class() 时,它一直显示为“列表”。我不希望将 C 转换为数据框;相反,我想保持原样。
以下是一些示例列表和我的尝试,根据以下有用的评论进行了更新:
a1 <- list( sublist1 = list(A= list(sub1= c(10, 40), sub2 = c(15, 35)), B=list(sub1 = c(100, 400), sub2 = c(150, 350)), C =c("abc","def")),
sublist2 = list(A= list(sub1= c(3, 4), sub2 = c(5, 6)), B=list(sub1 = c(7, 8), sub2 = c(9, 11)))
)
b_char <- as.character(c('2,3'))
typeof(b_char)
changetypefun <- function(x){
if (is.list(x)) lapply(x, changetypefun)
#else if (!is.list(x)) x #here I try to say if its not a list just return what it is
#else if (names(x) == 'C') # here I try to say if its the C object, return what it is.
#else if (typeof(x) == 'character') x #here and the statements below I try to say if it is a character or not a list, return it
#else if (class(x) == 'character') x
#else if (is.atomic(x)) x
else if (!is.list(x['C'])) x lapply(a1[['C']],paste0('as.',class(b_char)))
else as.data.frame(x)
}
result <- changetypefun(a1)
非常感谢您的帮助。
答:
2赞
dcsuka
8/20/2022
#1
对上一个问题的答案进行简单的修改就可以了。只需将子句更改为:else x
else as.data.frame(x)
a1 <- list( sublist1 = list(A= list(sub1= c(10, 40), sub2 = c(15, 35)), B=list(sub1 = c(100, 400), sub2 = c(150, 350)), C =c("abc","def")),
sublist2 = list(A= list(sub1= c(3, 4), sub2 = c(5, 6)), B=list(sub1 = c(7, 8), sub2 = c(9, 11)))
)
changetypefun <- function(x){
if (is.list(x)) {lapply(x, changetypefun)}
else {
if (is.character(x)) x
else as.data.frame(x)
}
}
changetypefun(a1)
评论
0赞
Divs
8/21/2022
谢谢!我一直在尝试理解这个功能。你能翻译一下吗?是 1) 检查 x 是否为列表,2) 如果是,请检查 x 并应用 Changefun,以及 3) 进入数据框?我不明白“其他”部分......
0赞
Divs
8/21/2022
另外,有没有办法将要转换为数据帧的列表索引(例如与子列表顺序关联的数字)传入,而不是将数据帧中最低级别的所有子列表传入?我的数据中有一个字符向量,我不想将其转换为数据帧。所以我想知道我是否可以为第二行代码创建一个条件,该代码行进行查找以获取我感兴趣的列表中的子列表名称/顺序。非常感谢!!
0赞
dcsuka
8/21/2022
除了@onyambu的解释之外,摆脱浏览列表循环的唯一方法是 else 子句。如果您查看的内容不是列表,则将其设置为数据帧,然后退出整个递归循环的子集。做你想做的事的最简单方法可能是在当前 if 和 else 子句之间添加一个。请注意,我们只说,而不是在结尾处保持其作为字符。该部分表示,如果它不是列表,则使其成为数据帧。这只发生在你退出之前。else if (x == c("your custom character vector")) x
x
as.data.frame(x)
else
0赞
Divs
8/23/2022
谢谢。我尝试了多种方法——我更新了上面的帖子。你知道我做错了什么吗?再次感谢!
0赞
dcsuka
8/23/2022
我根据一些建议进行了编辑。不确定您到底想要什么,a1 的预期输出会有所帮助。你是想把列表拉平吗?或者只是将所有字符都保留为向量?我的解决方案是后者。 做第一个。purrr::flatten
1赞
Stéphane Laurent
8/20/2022
#2
使用 rrapply 软件包:
library(rrapply)
rrapply(
a1,
condition = is.atomic,
f = as.data.frame
)
评论
0赞
Divs
8/21/2022
谢谢!!你能解释一下其中的逻辑吗?我对此不是很熟悉。这是什么条件“is.atomic”,当我们将 f = 设置为数据帧时,为什么我在我的环境中看不到 F?
0赞
Stéphane Laurent
8/21/2022
@Divs R 中有两种类型的向量:原子向量和列表。例如,是原子的。通常我们简单地说原子向量的“向量”。我不明白你的第二个问题。c(2, 3)
0赞
Divs
8/21/2022
感谢您的明确解释!对于第二个问题,我只是不确定“f = as.data.frame”是做什么的。它是否接受这个“f”对象并将其制作成数据帧?如果是这样,我的工作区中的 f 对象在哪里?非常感谢!
0赞
Stéphane Laurent
8/21/2022
@Divs以递归方式访问嵌套列表的元素。当它找到一个满足条件的元素(是原子的)时,它会将函数应用于该元素。rrapply
f
0赞
Divs
8/23/2022
谢谢。它怎么知道 f 是一个函数呢?
评论