R 更改嵌套列表的类型

R Change type of nested list

提问人:Divs 提问时间:8/20/2022 最后编辑:Divs 更新时间:8/23/2022 访问量:283

问:

更新: 我有一个嵌套列表,我正在尝试将嵌套列表最深层次的类更改为数据框。我不想在数据框中使用更高级别。我也有我尝试在子列表 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)

非常感谢您的帮助。

R 列表 递归 嵌套

评论


答:

2赞 dcsuka 8/20/2022 #1

对上一个问题的答案进行简单的修改就可以了。只需将子句更改为:else xelse 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")) xxas.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以递归方式访问嵌套列表的元素。当它找到一个满足条件的元素(是原子的)时,它会将函数应用于该元素。rrapplyf
0赞 Divs 8/23/2022
谢谢。它怎么知道 f 是一个函数呢?