【问题标题】:What exactly does sapply with '[' do?sapply 和 '[' 到底是做什么的?
【发布时间】:2015-08-24 21:46:08
【问题描述】:

我在 R 中浏览了一些关于 strsplit 的答案。示例文本:

fileName <- c("hello.w-rp-al",
              "how.nez-r",
              "do.qs-sdz",
              "you.d-aerd",
              "do.dse-e")

我想获得创建列表的第一个元素,并认为我可以使用诸如

之类的东西
fileNameSplit <- strsplit(fileName, "[.]")
node_1 <- fileNameSplit[0]
node_2 <- fileNameSplit[1]

但这没有用。

然后我发现this answer 建议使用sapply[。这确实有效。

d <- data.frame(fileName)
fileNameSplit <- strsplit(d$fileName, "[.]")
d$node_1 <- sapply(fileNameSplit, "[", 1)
d$node_2 <- sapply(fileNameSplit, "[", 2)

但是,我想弄清楚为什么。到底发生了什么,[ 与任何事情有什么关系?在我看来,这在语义上令人困惑。

【问题讨论】:

  • [ 是一个函数。请参阅 ?"["get("[") 的输出
  • 从子集的角度考虑。

标签: r string split


【解决方案1】:

sapply 对列表进行操作,列表是每个元素可以采用任何形式的向量。


在您的fileNameSplit 列表的特殊情况下,我们知道列表的每个元素都是包含两个元素的字符向量。

> fileNameSplit 
[[1]]
[1] "hello"   "w-rp-al"

[[2]]
[1] "how"   "nez-r"

[[3]]
[1] "do"     "qs-sdz"

[[4]]
[1] "you"    "d-aerd"

[[5]]
[1] "do"    "dse-e"

要从每个字符向量中提取第一个元素,我们必须遍历列表,这就是

sapply(fileNameSplit, `[`, 1)

确实如此。写成这样可能会更清楚

sapply(fileNameSplit, function(x) x[1])

?`[`?sapply 的文档解释了为什么较短的版本可以工作。

我们使用1,因为这是 R 中索引开始的地方(与其他从 0 开始的语言不同)。

【讨论】:

    【解决方案2】:

    R 非常类似于 LisP。符号[ 实际上是一个函数。当您编写mylist[1] 时,“幕后”实际发生的是,侧方括号内的编号或命名项目(在本例中只有一个)被提取并从“mylist”传递给[ 函数,其中成为第一个函数参数,所以它变成:

     `[`(mylist, 1)   # that will also succeed if you type it at the command line
    

    sapplylapply 都有一个尾随的三点参数。因此,作为第一个参数传递给[ 的一系列项目只是fileNameSplit 的子列表中的值,而1 正在作为第二个参数被回收,因此您将获得每个项目中的第一个项目那些子列表。 sapply 函数会创建一系列调用,例如:

     `[`(mylist[[1]], 1)   # as the first one with 2,3, ... in the [[.]] for succeeding calls
    

    然后将它们作为矩阵或列表重新运行(取决于它们是否都具有相同的长度以及“简化”参数的设置。)

    因为您使用了没有“简化”参数的sapply,所以使用默认的 TRUE,并将值传递给simplify2array,并作为向量结果返回给您,而不是本应返回的列表你刚刚用过lapply吗?

    【讨论】:

      猜你喜欢
      • 2015-06-29
      • 2015-08-06
      • 2013-09-02
      • 2014-01-02
      • 2013-10-10
      • 2017-05-08
      • 2022-01-20
      • 2012-10-17
      • 2017-06-15
      相关资源
      最近更新 更多