在 r 中分配和获取数据帧变量
assign and get for dataframe variables in r
如果我想让带有数字的变量可访问,例如在 for 循环中,我可以使用 get 和 assign:
for(i in 1:2){
assign(paste0('a',toString(i)),i*pi)
}
get('a2')
输出
[1] 6.283185
但是如果我想对数据框做类似的事情怎么办?
我想做类似的事情
df<-data.frame(matrix(ncol = 2,nrow = 3))
varnames <- c()
for(i in 1:2){
varnames <- c(varnames, paste0('a', toString(i)))
}
colnames(df) <- varnames
for(i in 1:2){
assign(paste0('df$a',toString(i)), rep(i*pi,3))
}
get(paste0('df$a',toString(2)))
但这实际上只是创建了名为 df$a1
、df$a2
的变量,而不是将 c(i*pi,i*pi,i*pi) 分配给数据帧的列 df
我真正想做的是能够像这样操作整个列(单个条目):
for(i in 1:2){
for(j in 1:3)
assign(paste0('df$a',toString(i),'[',toString(j),']'), i*pi)
}
get(paste0('df$a',toString(2),'[2]'))
我在哪里可以得到 df$a2[2]
。
我认为 python 字典之类的东西也可以。
而不是 assign
,直接执行 [
for(i in 1:2) df[[paste0('a', i)]] <- rep(i * pi, 3)
然后可以用
取值
df[[paste0('a', 2)]][2]
[1] 6.283185
assign
可以用,但是直接做的话不推荐
for(i in 1:2) assign("df",`[[<-`(df, paste0('a', i), value = i * pi))
df[[paste0('a', 2)]][1]
[1] 6.283185
get
应该在对象上,即 'df' 而不是列,即
get('df')[[paste0('a', 2)]][1]
首先,使用 assign
在全局环境中创建对象通常不是一个好主意。出于各种充分的理由,您应该优先创建一个命名列表,其中最重要的是能够迭代您创建的对象。
其次,请注意代码块:
varnames <- c()
for(i in 1:2){
varnames <- c(varnames, paste0('a', toString(i)))
}
colnames(df) <- varnames
可以用单行替换:
colnames(df) <- paste0("a", 1:2)
最后,您应该利用 R 的矢量化和使用 ["colname"]
符号进行子集化的能力。这完全消除了对显式循环的需要:
df[paste0("a", 1:2)] <- sapply(1:2, \(i) rep(i * pi, 3))
df
#> a1 a2
#> 1 3.141593 6.283185
#> 2 3.141593 6.283185
#> 3 3.141593 6.283185
如果我想让带有数字的变量可访问,例如在 for 循环中,我可以使用 get 和 assign:
for(i in 1:2){
assign(paste0('a',toString(i)),i*pi)
}
get('a2')
输出
[1] 6.283185
但是如果我想对数据框做类似的事情怎么办?
我想做类似的事情
df<-data.frame(matrix(ncol = 2,nrow = 3))
varnames <- c()
for(i in 1:2){
varnames <- c(varnames, paste0('a', toString(i)))
}
colnames(df) <- varnames
for(i in 1:2){
assign(paste0('df$a',toString(i)), rep(i*pi,3))
}
get(paste0('df$a',toString(2)))
但这实际上只是创建了名为 df$a1
、df$a2
的变量,而不是将 c(i*pi,i*pi,i*pi) 分配给数据帧的列 df
我真正想做的是能够像这样操作整个列(单个条目):
for(i in 1:2){
for(j in 1:3)
assign(paste0('df$a',toString(i),'[',toString(j),']'), i*pi)
}
get(paste0('df$a',toString(2),'[2]'))
我在哪里可以得到 df$a2[2]
。
我认为 python 字典之类的东西也可以。
而不是 assign
,直接执行 [
for(i in 1:2) df[[paste0('a', i)]] <- rep(i * pi, 3)
然后可以用
取值df[[paste0('a', 2)]][2]
[1] 6.283185
assign
可以用,但是直接做的话不推荐
for(i in 1:2) assign("df",`[[<-`(df, paste0('a', i), value = i * pi))
df[[paste0('a', 2)]][1]
[1] 6.283185
get
应该在对象上,即 'df' 而不是列,即
get('df')[[paste0('a', 2)]][1]
首先,使用 assign
在全局环境中创建对象通常不是一个好主意。出于各种充分的理由,您应该优先创建一个命名列表,其中最重要的是能够迭代您创建的对象。
其次,请注意代码块:
varnames <- c()
for(i in 1:2){
varnames <- c(varnames, paste0('a', toString(i)))
}
colnames(df) <- varnames
可以用单行替换:
colnames(df) <- paste0("a", 1:2)
最后,您应该利用 R 的矢量化和使用 ["colname"]
符号进行子集化的能力。这完全消除了对显式循环的需要:
df[paste0("a", 1:2)] <- sapply(1:2, \(i) rep(i * pi, 3))
df
#> a1 a2
#> 1 3.141593 6.283185
#> 2 3.141593 6.283185
#> 3 3.141593 6.283185