简体   繁体   English

应用数据框列分配

[英]Sapply dataframe column assignment

I want to rewrite some of the first lines from this question , and I can't figure out why my sapply line isn't working. 我想重写此问题的前几行, 我无法弄清楚为什么我的sapply行无法正常工作。

I want to turn these lines: 我想转这些行:

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)}

into: 成:

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) } )

but for some reason that sapply line gives me a new columns would leave holes after existing columns error, and I don't know why. 但是由于某些原因, sapply给我一个new columns would leave holes after existing columnsnew columns would leave holes after existing columns ,我也不知道为什么。

I've also tried 我也尝试过

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)

EDIT: 编辑:

When you assign new column in the mydata dataframe, it does it locally to the function. 当在mydata数据框中分配新列时,它将在本地对函数执行。 Any changes to the mydata dataframe does not apply in the parent environment of this function. mydata数据框的任何更改均不适用于此函数的父环境。

To see this effect, use a print statement inside the function. 若要查看此效果,请在函数内部使用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

To prevent this scoping issue you can use <<- instead of <- . 为了防止出现范围问题,您可以使用<<-代替<-

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

Note: using <<- approach is strongly discouraged due to confusions created later by it, when your code base grows and your computations involve multiple packages. 注意:强烈建议不要使用<<-方法,因为随着代码库的增加和计算涉及多个程序包,稍后会造成混乱。

Possible Solution: 可能的解决方案:

You have take the output of the sapply command and column bind with the mydata . 您已获取sapply命令的输出,并且将列与mydata绑定。

Try this: 尝试这个:

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) )
        ))

Output: 输出:

#     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

I was not able to determine why your code wasn't working, but it has something to do with the columns not being defined before you run sapply . 我无法确定为什么您的代码无法正常工作,但这与在运行sapply之前未定义列sapply So if you define your data.frame beforehand, it works 因此,如果您事先定义了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) } )

EDIT: 编辑:

You can use the following code instead 您可以改用以下代码

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) } ))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM