【问题标题】:column full of NA using lapply in a data.table R在data.table R中使用lapply充满NA的列
【发布时间】:2016-07-12 10:10:32
【问题描述】:

我在 data.table 中使用 lapply 时遇到问题。这里有两个例子:

library(data.table)
 library(lubridate)

test <- function(x) 
{
  if(is.na(x)) return(NA)
  if(x=="") return(NA)
  if(substr(x,3,3)=="/") return(as_date(x,"%d/%m/%Y"))
  return(2)
}

x1<-data.table(v1=c("","07/06/2016","",NA), v2=c("2004-06-18","","2004-06-18","2004-06-18"))
x1[,lapply(.SD,test)]

x2<-data.table(v1=c("2004-06-19","2004-06-18","",NA),v2=c("2004-06-18","","2004-06-18","2004-06-18"))
x2[,lapply(.SD,test)]

在第一个示例中,lapply 之后的第一列是NA,但我想获取的是NA, 2016-06-07, NA, NA

在第二个例子中,第一列的最后两行是错误的,因为每行包含 2 但我认为应该包含NA

我不明白 R 在这里如何看待NA。为了得到我想要的,我错过了什么?

【问题讨论】:

  • 上面的.SD是什么?
  • 这允许我们在所有列上应用一个函数。我们还可以放置另一个参数“.SDcols = c(...)”以将函数应用于特定列。我认为这仅用于数据表。

标签: r data.table lapply


【解决方案1】:

经过多次尝试,答案是data.table 将列视为变量,而.SD 是一个列表,其元素是以列为变量,因此在应用函数时,如这里测试,此函数必须将列表作为参数。

以下是您应该更改的内容:

testList <- function(x) 
{
  lapply(x,test)
}

x1[,lapply(.SD,testList)]

如果有人知道其他解决方案,请随时分享。

【讨论】:

    【解决方案2】:

    首先,我无法在不引发错误的情况下运行您的示例。 data.tables 的第二列属于“日期”类,但 "" 条目不是日期。当它打印时,它的格式看起来像NA。尝试运行is.na(x1$v2[2])x1$v2[2] == ""

    另外,您的矢量化似乎有问题。

    尝试运行test(x1$v1)。注意警告信息。 is.na(x) 返回一个逻辑向量,但 if 只使用向量中的第一个元素。

    In addition: Warning message:
    In if (is.na(x)) return(NA) :
      the condition has length > 1 and only the first element will be used
    

    您也许可以通过应用到每一行来修复它:

    x1[, lapply(.SD, test), by = 1:nrow(x1)]
    

    否则,您需要修改 test 函数以接受字符串向量并返回结果向量。但是你真的应该考虑返回一个单一类型的向量。

    最后,我不明白这个例子中lubridate 的用途。为什么不使用as.Date(x,"%d/%m/%Y")。你从as_date得到什么?

    编辑

    你可以重写你的函数来处理向量:

    test <- function(x) 
    {
      ans <- rep.int(2, length(x))
      ans[is.na(x) | x == ""] <- NA
      dates <- grepl('../', x)
      ans[dates] <- as_date(x[dates], "%d/%m/%Y") 
    
      return(ans)
    }
    

    【讨论】:

    • 感谢@joeyreid 的回答。正如我在回答中所说,您对矢量化是正确的。 by = 1:nrow(x1) 技巧不起作用,这太糟糕了,因为做 2 lapply 很慢。不是在这个简短的例子上,而是在我使用它的桌子上。如果您知道有效的方法,我将不胜感激!至少,lubridate 被用于其他目的,在我的示例中我没有更改它,但你是对的,它在这里并不是特别有用
    猜你喜欢
    • 2020-03-12
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    相关资源
    最近更新 更多