如何确定字符向量是否是有效的数字或整数向量

时间:2014-06-09 21:11:14

标签: r lapply rbind

我试图将嵌套列表结构转换为数据帧。该列表看起来类似于以下内容(它是使用httr包读取的解析JSON中的序列化数据)。

  myList <- list(object1 = list(w=1, x=list(y=0.1, z="cat")), object2 = list(w=NULL, x=list(z="dog")))

编辑:我原来的示例数据太简单了。实际数据是不规则的,这意味着并非每个对象都存在所有变量,并且一些列表元素为NULL。我编辑了数据以反映这一点。

unlist(myList)在递归展平列表方面做得很好,然后我可以使用lapply很好地展平所有对象。

  flatList <- lapply(myList, FUN= function(object) {return(as.data.frame(rbind(unlist(object))))}) 

最后,我可以使用plyr::rbind.fill

来关闭它
  myDF <- do.call(plyr::rbind.fill, flatList)
  str(myDF)

  #'data.frame':    2 obs. of  3 variables:
  #$ w  : Factor w/ 2 levels "1","2": 1 2
  #$ x.y: Factor w/ 2 levels "0.1","0.2": 1 2
  #$ x.z: Factor w/ 2 levels "cat","dog": 1 2

问题是w和x.y现在被解释为字符向量,默认情况下会将其解析为数据帧中的因子。我相信unlist()是罪魁祸首,但我无法找到另一种递归展平列表结构的方法。解决方法是对数据帧进行后处理,然后分配数据类型。确定向量是否是有效数值或整数向量的最佳方法是什么?

6 个答案:

答案 0 :(得分:15)

正如所讨论的here,检查as.numeric是否返回NA值是检查字符串是否包含数字数据的简单方法。现在你可以做类似的事情:

myDF2 <- lapply(myDF, function(col) {
  if (suppressWarnings(all(!is.na(as.numeric(as.character(col)))))) {
    as.numeric(as.character(col))
  } else {
    col
  }
})
str(myDF2)
# List of 3
#  $ w  : num [1:2] 1 2
#  $ x.y: num [1:2] 0.1 0.2
#  $ x.z: Factor w/ 2 levels "cat","dog": 1 2

答案 1 :(得分:1)

您可以使用plyr::ldply

ldply(myList,.fun=function(x)data.frame(x))

      .id w x.y x.z
1 object1 1 0.1 cat
2 object2 2 0.2 dog

答案 2 :(得分:1)

我没有看到plyr :: ldply比常规基础R方法有任何优势:

 do.call(rbind, lapply(myList, data.frame) )
#-------------

        w x.y x.z
object1 1 0.1 cat
object2 2 0.2 dog

由于误导数据而不考虑其内在结构而误导了数据,因此出现了麻烦。

答案 3 :(得分:1)

当包含NA时,@ josliber的功能不起作用(尽管它很好地回答了样本数据的问题)。 @Amy M&#39的功能应该可以工作,但需要加载Hmisc包。

这样的事情:

can.be.numeric <- function(x) {
    stopifnot(is.atomic(x) || is.list(x)) # check if x is a vector
    numNAs <- sum(is.na(x))
    numNAs_new <- suppressWarnings(sum(is.na(as.numeric(x))))
    return(numNAs_new == numNAs)
}

在输入向量中计算NA s,在NA的输出中计算as.numeric() s,如果向量可以安全地&#34;则返回TRUE。转换为numeric(即不添加任何额外的NA值)。

答案 4 :(得分:0)

如果您只想转换在读入时被错误归类为字符的全数字向量,您还可以使用all.is.numeric包中的Hmisc函数:

myDF2 <- lapply(myDF, Hmisc::all.is.numeric, what = "vector", extras = NA)

如果向量仅包含数字,则选择what = "vector"会将向量转换为数字。 NAs或其他类型的缺失值将阻止转换,除非它们在上面的extras参数中指定。

但请注意,如果应用于包含Date或POSIXct向量的整个data.frame,这些也将转换为数字。为了防止这种情况,你可以将它包装在一个函数中,如下所示:

catchNumeric <- function(dtcol) {
  require(Hmisc)
  if (is.character(dtcol)) {
    dtcol1 = all.is.numeric(dtcol, what = "vector", extras = NA)
  } else {
    dtcol1 = dtcol
  }
  return(dtcol1)
}

然后应用于您的data.frame:

myDF2 <- lapply(myDF, catchNumeric)

答案 5 :(得分:0)

如果您有一个包含字符串的列表或向量,并且您只想将数字转换为数字,则可能的解决方案是:

public void moveToBack(ViewGroup viewGroup, View v) {
    int s = 1;
    for (int i = 1; i < viewGroup.getChildCount(); i++) {
        if (viewGroup.getChildAt(1) == v) {
            s = 2;
        } else {
            viewGroup.getChildAt(s).bringToFront();
        }
    }
}