如何在数据框中使用`assign()`或`get()`函数操作指定的列名?

6
有没有一种方法可以将值分配给数据框中的特定列?例如,
dat2 = data.frame(c1 = 101:149, VAR1 = 151:200)    
j = "dat2[,"VAR1"]"  ## or, j = "dat2[,2]"
assign(j,1:50)

上述方法不起作用。这个也不行:
j = "dat2"
assign(get(j)[,"VAR1"],1:50)

你需要更详细地解释为什么要这样做。如果有需要的话,你可以使用foo='VAR1'; dat2[,foo]<-1:50替代,并且仍然可以传递你的字符串。 - Justin
为什么?-- 是为了创建一堆任意命名的数据框,并在其中填充特定列。我知道使用列表结构更可取;然而,拥有另一个选项会很有用。 - baha-kev
2个回答

16

假设我们有一个有效的数据框,每个数据框有50行

dat2 <- data.frame(c1 = 1:50, VAR1 = 51:100)

1. 如果可以避免,不要使用 assignget

"dat2[,"VAR1"]"R 中无效。

您也可以从 assign 的帮助页面中注意到这一点

assign 不分派赋值方法,因此不能用于设置向量、名称、属性等的元素。

请注意,对附加列表或数据框的赋值会更改所附加的副本,而不是原始对象:请参见 attach 和 with。

数据框的列是列表的一个元素

你要找的是 [[<-

# assign the values from column (named element of the list) `VAR1`
j <- dat2[['VAR1']] 

如果您想在dat2中为VAR1分配新值,

dat2[['VAR1']] <- 1:50

你问题的答案....

使用getassign完全可以通过字符字符串进行操作。


assign('dat2', `[[<-`(get('dat2'), 'VAR1', value = 2:51))

其他方法

data.table::set

如果你想要在data.framedata.table内通过引用进行修改(仅替换一个已存在的列),则可以使用data.table包中的set函数(即使对于data.frames也适用)。

library(data.table)
set(dat2, j = 'VAR1', value = 5:54)

evalbquote

dat1 <- data.frame(x=1:5)
dat2 <- data.frame(x=2:6)



for(x in sapply(c('dat1','dat2'),as.name)) {
  eval(bquote(.(x)[['VAR1']] <- 2:6))
}

eapply

或者如果您使用单独的环境:

ee <- new.env()
ee$dat1 <- dat1
ee$dat2 <- dat2

# eapply returns a list, so use list2env to assign back to ee
list2env(eapply(ee, `[[<-`, 'y', value =1:5), envir = ee)


1
@krlmlr -- 我更喜欢使用[[<-进行单个赋值。 - mnel
请注意,我的问题主要涉及到获取/分配数据框 - 换句话说,我想通过字符值来命名和引用数据框。我认为set()可以这样工作,只需要将set(dat2, ...)替换为set(get(), ...)即可。谢谢。 - baha-kev
@baha-kev -- set 不会创建新的列,只是替换现有列中的值。 - mnel
啥?set 不是基础或推荐的 R 包中的函数。 - IRTFM
你上一个“非常丑陋”的方法正是我在寻找的。如果你能把它移到你的答案顶部,那就太好了。谢谢! - baha-kev
显示剩余2条评论

6
set2 <- function(x,  val) {
   eval.parent(substitute(x <- val))
 }

> dat2 = data.frame(c1 = 101:150, VAR1 = 151:200)
> set2(dat2[["VAR1"]], 1:50)
> str(dat2)
'data.frame':   50 obs. of  2 variables:
 $ c1  : int  101 102 103 104 105 106 107 108 109 110 ...
 $ VAR1: int  1 2 3 4 5 6 7 8 9 10 ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接