将第一行添加到空 data.frame 时,行号不同(NA 与 1)

标签 r dataframe

我想了解为什么这两种索引空 data.frame 的方法会导致 NA 行号仅分配给第一行:

方法一:

df <- data.frame(Number=numeric(), Text=character(), stringsAsFactors = FALSE)
df[1,]$Number <- 123456
df[1,]$Text <- "abcdef"
df[2,]$Number <- 456789
df[2,]$Text <- "abcdef"

输出 1:

> df
   Number   Text
NA 123456 abcdef
2  456789 abcdef


方法 2:
df <- data.frame(Number=numeric(), Text=character(), stringsAsFactors = FALSE)
df[1,1] <- 123456
df[1,2] <- "abcdef"
df[2,1] <- 456789
df[2,2] <- "abcdef"

输出 2:

> df
  Number   Text
1 123456 abcdef
2 456789 abcdef


我看到的唯一区别是第一种方法使用列名而不是列号访问 data.frame,但我不明白为什么这会导致 NA 行号被分配给第一个观察值,因为行号似乎从第二行开始按预期工作。

最佳答案

好吧,这个答案最重要的部分是应该避免这样的代码。将数据逐行添加到 R 中的 data.frame 是非常低效的(参见 R Inferno 的 Circle 2 )。几乎总是有更好的方法来做到这一点,这取决于你到底在做什么。

但是在了解这里发生的事情时。所有这些都归结为 $.data.frame<-[.data.frame[<-.data.frame 函数。在第一种情况下,与

df[1,]$Number <- 123456

你首先做的是调用 [<-.data.frame 的子集。当您要求一行不存在的 data.frame 时,您会得到一堆 NA 值(包括行名称)。所以现在你有一个空的 data.frame,列和行名称中有 NA 值。现在您调用 $<-.data.frame 来更新 Number 列。您不更新行号。然后将这个新值传递给 [<-.data.frame 以将其合并回 data.frame。当此命令运行时,它会检查以确保没有重复的行名称。对于第一行,由于只有一行且名称为 NA,因此保留该名称。但是,当存在重复名称时,该函数会用行号的索引替换这些值。这就是为什么您在第一行获得 NA,但是当它尝试添加下一行时,它再次尝试 NA,但发现这是重复的,因此它必须选择一个新名称。 (看看当你尝试 df[1:2,]$Number <- 123456 然后 df[3,]$Number <- 456789 时会发生什么)

另一方面,当你做
df[1,1] <- 123456

这不会首先进行子集设置以创建缺少行名称的行。您可以直接跳过 $.data.frame<-[.data.frame 进行赋值。在这种情况下,它不必合并具有 NA 行名称的新行,它可以立即创建该行并分配一个行名称。这只是调用赋值运算符的一个特殊属性,必须先进行提取。您可以使用 debug(`[<-.data.frame`) 来打开调试器,以查看具体是如何发生的。

所以第一种方法基本上是做三个步骤:1) 提取 df[1,] ,2) 更改数字列的值,然后 3) 将该新值合并回 df[1,] 。第二种方法跳过第一个步骤,只是直接将值合并到 df[1,] 中。真正的区别在于每个函数如何为尚不存在的行选择行名称。

关于将第一行添加到空 data.frame 时,行号不同(NA 与 1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51387451/

相关文章:

r - 如何使用group_by()和summary()来统计数据点的出现次数?

r - 将 24 小时日期格式转换为 R 中的 12 小时格式

r - 如何删除在R中具有分类值的多列?

python - 选择 3 个 Pandas 列中 3 个可能值中的最低值

python - 如何将列的值复制到新列中

Python - 访问二维列表中命名元组的一部分

string - R中用空格分割不均匀字符串

r - 你如何格式化多行 R 包消息?

r - 在 TERR 中运行 apply() 时为 "Subscript out of bounds",但在普通 R 中工作

python - 重组DataFrame并写入SQL数据库