【问题标题】:R: strsplit in each column; Error: replacement element 1 has [y] rows to replace 1 rowsR:strsplit 在每一列;错误:替换元素 1 有 [y] 行来替换 1 行
【发布时间】:2018-05-30 17:58:36
【问题描述】:

我正在使用 R 中的数据框(我将其称为“字母”),其中有 15 行乘 2 列。每列 2 包含一个字符串,如“A|B|C|D|E”。我想在每个地方分割字符串 a |似乎得到了向量 c("A", "B", "C", "D", "E")。这是我如何做到这一点的最佳想法:

for(i in 1:nrow(letters)){
  letters[i,2] <- strsplit(letters[i,2], split = "[|]")
}

我收到了与here 讨论的类似错误(“替换有 [x] 行,数据有 [y]”),它似乎试图为输出向量的每个索引创建一个单独的列。我敢肯定这是一个简单的问题,但我是 R 新手并且卡住了。

【问题讨论】:

  • 尝试只运行strsplit(letters[i,2], split = "[|]")并检查输出以进行调试
  • @Tung &gt; strsplit(letters[i,2], split = "[|]") 返回[[1]] [1] "A" "B" "C" "D" "E"

标签: r strsplit


【解决方案1】:

strsplit(letters[i,2], split = "[|]")[[1]] 是您要查找的内容吗?您将无法将该向量放回 letters[i,2],尽管它的长度为 5(而不是 1)。

【讨论】:

  • 是的,这就是我要找的。我没有意识到您不能将向量存储在数据框的单元格中。
  • 如果我最终要问的是:哪些行包含“A”,你会建议做什么?哪个包含“D”?所以我需要一个与每个行名关联的列表?
  • 使用grepl("A", letters[[2]])判断每个值是否包含"A"
【解决方案2】:

您的第二列是(我认为)一个字符向量。 strsplit,正如它在文档中提到的 (?strsplit) 返回一个列表。在我们了解为什么您的具体情况发生之前,一些一般性建议:

  1. 创建一个新列而不是替换现有列。这样做的额外好处是不会丢失原始值。
  2. 仅用同一类的新值替换列中的值(例如,字符替换字符,整数替换整数)。

所以我建议添加一个新的拆分值列:

letters[["splits"]] <- strsplit(letters[[2]], split = "|", fixed = TRUE)

您现在有一个列表列,该列的每一行都有一个由原始值拆分的字母组成的向量。

您的问题发生的原因

让我们剖析赋值语句:

letters[i,2] <- strsplit(letters[i,2], split = "[|]")

&lt;- 的左侧是letters[i, 2],也就是data.framedata.frame 将其所有数据存储在一个列表中。 R 允许我们使用这个事实,尤其是在赋值中。我们可以添加或替换列,就像添加或替换列表中的项目一样。

# This...
letters[, "one"] <- 1
letters[, "two"] <- 2
# is effectively the same as this
letters[, c("one", "two")] <- list(1, 2)

-&gt; 的右侧,我们调用了strsplit(),它返回一个list。如上例所示,如果将列表分配给data.frame 的子集,它将被强制转换为data.frame 本身。列表的每个元素都将被视为一列。所以,任务是这样进行的:

  1. 如果letters[i,2]"A|B|C|D|E",那么strsplit(letters[i,2], split = "[|]")list(c("A", "B", "C", "D", "E"))
  2. 分配检查双方,并将data.frame 视为“更高”类型,因此它将列表强制为data.frame。右侧现在实际上是 data.frame(c("A", "B", "C", "D", "E"))
  3. 现在它尝试将具有 1 列和 5 行data.frame 分配给具有 1 列和 1 行 的子集。这些尺寸不匹配,因此它会从右侧(仅第一行)获取尽可能多的内容并警告您发生的情况。

为什么建议的作业有效

那为什么没有强制呢?

letters[["splits"]] <- strsplit(letters[[2]], split = "|", fixed = TRUE)

左侧使用[[ 子集(将data.frame 视为列表)添加或替换"splits" 列。所以从来没有强制执行过。

此外,data.frame 可以将list 作为列,就像list 可以将list 作为元素一样。 data.frame 列只需要满足两件事:

  1. 它必须是一个向量。
  2. 其长度必须等于data.frame 中的行数(必要时尝试回收)。

list 是一种向量。并且strsplit() 返回一个与其输入长度相同的列表,因此满足两个条件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 2015-07-01
    • 2018-04-10
    • 2018-02-28
    • 2011-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多