Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 更改嵌套列表中元素的数据类型_R - Fatal编程技术网

R 更改嵌套列表中元素的数据类型

R 更改嵌套列表中元素的数据类型,r,R,是否可以扫描列表中具有特定名称的元素,并更改其数据类型,但保留其值 例如,以下列表包含“character”或“numeric”类的元素“N” x = list(list(N=as.character(1)), list(a=1,b=2,c="another element",N=as.character(5)), list(a=2,b=2,N=as.character(7),c=NULL), list(a=2,b=2,list(N=as

是否可以扫描列表中具有特定名称的元素,并更改其数据类型,但保留其值

例如,以下列表包含“character”或“numeric”类的元素“N”

x = list(list(N=as.character(1)),
         list(a=1,b=2,c="another element",N=as.character(5)), 
         list(a=2,b=2,N=as.character(7),c=NULL), 
         list(a=2,b=2,list(N=as.character(3))))
然后应成为:

x = list(list(N=as.numeric(1)),
         list(a=1,b=2,c="another element",N=as.numeric(5)), 
         list(a=2,b=2,N=as.numeric(7),c=NULL), 
         list(a=2,b=2,list(N=as.numeric(3))))
为了清楚起见,该解决方案应该允许更深的嵌套,并尊重名称不是“N”的字段的数据类型。我还没有找到一个适用于任意结构列表的通用解决方案

我已经尝试了以下解决方案:


a使用
lappy
在列表元素上重复该过程,条件是检查您感兴趣的元素,这样您就不会无意中将元素添加到子列表中:

x <- lapply(x, function(i) {

    if(length(i$N) > 0) {

        i$N <- as.numeric(i$N)

    }

    return(i)

})
x0){

i$N仅适用于包含数字或带数字字符串的列表的解决方案:

x <- list(list(N=as.character(1)),
         list(a=1,b=2,N=as.character(5)), 
         list(a=2,b=2,N=as.character(7)), 
         list(a=2,b=2))

y1 <- lapply(x, function(y) lapply(y, as.numeric))

y2 <- list(list(N=as.numeric(1)),
         list(a=1,b=2,N=as.numeric(5)), 
         list(a=2,b=2,N=as.numeric(7)), 
         list(a=2,b=2))

identical(y1,y2)
# [1] TRUE
由提供的答案可进一步概括为:

is_num <- function(x) grepl("^[-]?[0-9]+[.]?[0-9]*|^[-]?[0-9]+[L]?|^[-]?[0-9]+[.]?[0-9]*[eE][0-9]+",x)

as_num <- function(x) {
if (is.null(x)||length(x) == 0) return(x)
if (class(x)=="list") return(lapply(x, as_num))
if (is.character(x) & is_num(x)) return(as.numeric(x))
return(x)
}
y <- as_num(z)
identical(y,z)

is_num我看不出如何在任意复杂度下实现这一点。您可以使用
rappy
强制所有字符为数字,例如
rappy(x,as.numeric,how=“replace”)
。是的,但由于此解决方案更改了所有元素,因此无法解决任意复杂性的问题-我更改了示例以使其更清晰我最初也尝试过此方法,但不幸的是,对于N位于任意深度的列表,此方法不起作用。我更改了示例以使此方面更清晰。嗯,它应该不起作用ter每个列表中的
N
在哪里,或者是否有
N
。它是如何失败的?如果N嵌套的深度超过一层,它就会失败。我想一个交互版本会适用于嵌套>1Ah的列表,好吧。所以你修改了问题,将其扩展到列表列表,而不仅仅是列表列表。这确实适用于示例b但不适用于更复杂的列表。我已经更改了示例以使其更清晰。我下次会这样做。虽然我确实没有在示例中反映这一点,但最初的问题已经表明,我正在寻找一种也适用于更复杂列表的解决方案。@JoostKeuskamp我已经在嵌套列表上测试了比您的e示例和它的工作。然而,我想知道它是否也适用于嵌套列表。@marcSandri这是一个很好的开始,但在我的列表中失败了。如果可以的话,我将根据您的工作代码发布一个附加答案。编辑您的旧问题并在文本末尾添加列表。编写“编辑”以清楚显示che添加。
library(rlist)

x = list(list(N=as.character(1)),
         list(a=1,b=2,c="another element",N=as.character(5)), 
         list(a=2,b=2,N=as.character(7),c=NULL), 
         list(a=2,b=2,list(N=as.character(3))))

# Test if the string contains a number
is_num <- function(x) grepl("[-]?[0-9]+[.]?[0-9]*|[-]?[0-9]+[L]?|[-]?[0-9]+[.]?[0-9]*[eE][0-9]+",x)

# A recursive function for numeric convertion of strings containing numbers
as_num <- function(x) {
   if (!is.null(x)) {
     if (class(x)!="list") {
       y <- x
       if (is.character(x) & is_num(x)) y <- as.numeric(x)
     } else {
       y <- list.apply(x, as_num)
     }
   } else { 
     y <- x
   }
   return(y)
}

y <- list.apply(x, as_num)

z = list(list(N=as.numeric(1)),
         list(a=1,b=2,c="another element",N=as.numeric(5)), 
         list(a=2,b=2,N=as.numeric(7),c=NULL), 
         list(a=2,b=2,list(N=as.numeric(3))))

identical(y,z)
# [1] TRUE
is_num <- function(x) grepl("^[-]?[0-9]+[.]?[0-9]*|^[-]?[0-9]+[L]?|^[-]?[0-9]+[.]?[0-9]*[eE][0-9]+",x)

as_num <- function(x) {
if (is.null(x)||length(x) == 0) return(x)
if (class(x)=="list") return(lapply(x, as_num))
if (is.character(x) & is_num(x)) return(as.numeric(x))
return(x)
}
y <- as_num(z)
identical(y,z)