为什么 R 允许通过尾部切片创建新列?

D B*_*lta 17 r dataframe

如果我创建一个数据框

df = data.frame(a=c(1,2,3), b=c(4,5,6))
Run Code Online (Sandbox Code Playgroud)

为什么这段代码

df$z[c(1,2)] = c(7,8)
Run Code Online (Sandbox Code Playgroud)

产生这个错误

Error in `$<-.data.frame`(`*tmp*`, z, value = c(7, 8)) : 
replacement has 2 rows, data has 3
Run Code Online (Sandbox Code Playgroud)

这段代码有效吗?

df$z[c(2,3)] = c(7,8)
Run Code Online (Sandbox Code Playgroud)
df
  a b  z
1 1 4 NA
2 2 5  7
3 3 6  8
Run Code Online (Sandbox Code Playgroud)

jbl*_*d94 6

如果赋值是一个向量,R 似乎会创建z要添加到 的向量data.frame,并且该向量需要与 中的数字行具有相同的长度data.frame

如果您使用对象,会更清楚地显示发生的情况list

df <- list(a = 1:3, b = 4:6)
df$z1[1:2] <- 7:8
df$z2[2:3] <- 7:8
df$z3[c(1,3)] <- 7:8
df
#> $a
#> [1] 1 2 3
#> 
#> $b
#> [1] 4 5 6
#> 
#> $z1
#> [1] 7 8
#> 
#> $z2
#> [1] NA  7  8
#> 
#> $z3
#> [1]  7 NA  8
data.frame(df)
#> Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, : arguments imply differing number of rows: 3, 2
data.frame(df[-3])
#>   a b z2 z3
#> 1 1 4 NA  7
#> 2 2 5  7 NA
#> 3 3 6  8  8
Run Code Online (Sandbox Code Playgroud)


akr*_*run 5

错误来自$<-.data.frame函数

> `$<-.data.frame`
function (x, name, value) 
{
    cl <- oldClass(x)
    class(x) <- NULL
    nrows <- .row_names_info(x, 2L)
    if (!is.null(value)) {
        N <- NROW(value)
        if (N > nrows) 
            stop(sprintf(ngettext(N, "replacement has %d row, data has %d", 
                "replacement has %d rows, data has %d"), N, nrows), 
                domain = NA)
...
Run Code Online (Sandbox Code Playgroud)

N > nrows即满足 的条件

> NROW(c(7, 8))
[1] 2
> .row_names_info(df, 2L)
[1] 3
Run Code Online (Sandbox Code Playgroud)

这是通过traceback()错误确认的

> traceback()
3: stop(sprintf(ngettext(N, "replacement has %d row, data has %d", 
       "replacement has %d rows, data has %d"), N, nrows), domain = NA)
2: `$<-.data.frame`(`*tmp*`, z, value = c(7, 8))
1: `$<-`(`*tmp*`, z, value = c(7, 8))
Run Code Online (Sandbox Code Playgroud)

  • 很不错。我正在跟踪错误的函数“[&lt;-.data.frame”! (3认同)