【问题标题】:Sapply dataframe column assignmentSapply 数据框列分配
【发布时间】:2018-09-02 14:35:18
【问题描述】:

我想重写this question 的一些第一行,但我不知道为什么我的sapply 行不起作用。

我想转这些线:

cols <- sample(c(1:5), 1)
label <- rep(paste0("label ", seq(from=1, to=10)))
mydata <- data.frame(label)
for (i in 1:cols) {mydata[,i+1] <- sample(c(1:10), 10)}

进入:

cols <- sample(c(1:5), 1) 
mydata <- data.frame(rep(paste0("label ", seq(1,10))))
sapply(1:cols, function(x) { mydata[,(x+1)] <- sample(c(1:10), 10) } )

但由于某种原因,sapply 行给了我一个new columns would leave holes after existing columns 错误,我不知道为什么。

我也试过

sapply(1:cols, function(x) { mydata[,(x+1)] <- sample(c(1:10), 10); mydata } )
Map(function(x, mydata1) {mydata1[,(x+1)] <- sample(c(1:10), 10)}, x = 1:cols, mydata1 = mydata)

【问题讨论】:

    标签: r dataframe apply assign sapply


    【解决方案1】:

    我无法确定您的代码为何不起作用,但这与在您运行 sapply 之前未定义的列有关。因此,如果您事先定义 data.frame,它就可以工作

    cols <- sample(c(1:5), 1) 
    mydata <- data.frame(matrix(rep(0, 10*(cols+1)), ncol = cols+1))
    mydata[, 1] <- rep(paste0("label ", seq(1,10)))
    sapply(1:cols, function(x) {
      mydata[, x+1] <- sample(c(1:10), 10) } )
    

    编辑:

    您可以改用以下代码

    cols <- sample(c(1:5), 1) 
    mydata <- data.frame(rep(paste0("label ", seq(1,10))),
                         sapply(1:cols, function(x) {sample(c(1:10), 10) } ))
    

    【讨论】:

    • 谢谢,这很有趣。它肯定与数据框在技术上是一个列表有关。但是,该 sapply 函数的输出是一个矩阵,并且没有任何标签。
    • 虽然可行:cols &lt;- sample(c(1:5), 1); mydata &lt;- matrix(rep(0, 10*(cols)), ncol = cols); mydata &lt;- sapply(1:cols, function(x) mydata[, x] &lt;- sample(c(1:10), 10)); mydata &lt;- data.frame(rep(paste0("label ", seq(1,10))), mydata)
    • @smanski 在两行中为我提供了一个非常优雅的解决方案,对我来说效果很好。您的回答也很有帮助,这就是我投赞成票的原因,但您的解决方案不那么简洁。
    • 是的,我说的是@smanski 在编辑中添加的答案部分。
    【解决方案2】:

    编辑:

    当您在 mydata 数据框中分配新列时,它会在本地对函数执行此操作。对 mydata 数据框的任何更改都不适用于此函数的父环境。

    要查看此效果,请在函数内使用print 语句。

    mydata <- data.frame( label = rep(paste0("label ", seq(1,10))))
    sapply( 1:cols, function(x) { 
      mydata[[(x+1)]] <- sample(c(1:10), 10)
      print(mydata)
      } )
    mydata
    

    为防止出现此范围问题,您可以使用 &lt;&lt;- 而不是 &lt;-

    sapply(1:cols, function(x) { mydata[,(x+1)] <<- sample(c(1:10), 10) } )
    

    注意:强烈建议不要使用&lt;&lt;- 方法,因为当您的代码库增长并且您的计算涉及多个包时,它会造成混淆。

    可能的解决方案:

    您已经获取了sapply 命令的输出并将列与mydata 绑定。

    试试这个:

    set.seed(1L)
    cols <- sample(c(1:5), 1) 
    print(cols) # [1] 2
    mydata <- data.frame( label = rep(paste0("label ", seq(1,10))))
    do.call("cbind",
            list( mydata,
                  sapply( seq_len(cols), function(x) sample(c(1:10), 10) )
            ))
    

    输出:

    #     label    1  2
    # 1   label 1  4  2
    # 2   label 2  6  7
    # 3   label 3  8  4
    # 4   label 4  2  6
    # 5   label 5  9  3
    # 6   label 6  5  8
    # 7   label 7  3  5
    # 8   label 8  7 10
    # 9   label 9  1  9
    # 10 label 10 10  1
    

    【讨论】:

      猜你喜欢
      • 2021-10-16
      • 1970-01-01
      • 2014-02-07
      • 1970-01-01
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多