【问题标题】:Variably assign value to particular subset of a variable in a loop in R [duplicate]在R中的循环中为变量的特定子集变量赋值[重复]
【发布时间】:2015-02-06 04:54:22
【问题描述】:

再试一次,这里有一个更清晰的帐户。

感谢您的回复,但我无法让这些解决方案对我有用;我可能把这个问题和我的例子混淆了。我会更具体的。

这是我在填充新子集之前需要调整的数据

> clientdata$Burn1
 [1] 4 3 3 3 2 2 2 3 2 3 2 4 3 2 2 2 2 3 3 3 4 3 3 2 2 2 3 3 4 2 2 2 1 4 2 4 2 3 3 3 4 2 4 3 3 2 3 2 2 3 4 3 3 2 3 3 2 2 3 2 2 2 2 3 2 3 3
> clientdata$Burn2
 [1] 2 3 3 2 2 2 2 3 3 4 2 3 3 2 3 3 3 3 4 3 3 4 3 2 2 2 2 4 3 2 4 2 3 3 3 4 3 3 2 2 4 2 3 2 2 2 3 2 3 3 4 3 3 2 3 2 2 2 2 2 2 2 2 2 2 3 3
> clientdata$Forw2
 [1] 3 3 3 3 3 4 3 3 3 4 4 3 4 3 3 3 4 3 3 3 4 2 3 2 2 2 4 4 4 2 4 3 3 4 3 4 3 2 4 3 3 3 3 3 2 3 3 2 2 3 4 3 4 2 3 3 4 2 3 3 3 3 3 3 4 3 3
> clientdata$Harm1
 [1] 2 2 2 2 3 2 2 2 2 4 2 3 4 2 3 3 3 3 3 3 2 2 2 2 2 3 4 1 2 2 2 1 1 2 2 4 3 3 2 4 1 3 2 3 2 2 2 2 2 2 4 2 3 2 3 2 2 1 2 2 1 2 2 2 2 1 2
> clientdata$Innov1
 [1] 3 3 3 3 4 4 3 2 3 4 4 3 4 3 4 4 4 3 4 3 4 2 3 2 3 3 4 4 4 2 4 3 1 4 4 3 3 3 4 4 4 3 1 4 3 3 4 3 2 3 3 2 4 2 3 1 4 2 3 2 3 1 4 3 3 4 2

这是我的变量名向量:

> rev.items.new
[1] "clientdata$Harm1_r"  "clientdata$Innov1_r" "clientdata$Burn1_r"  "clientdata$Forw2_r"  "clientdata$Burn2_r"

现在我希望能够做到这一点,但不是针对那些特定子集进行硬编码(它们可能会因下一个客户而改变);基本上按我的列表填充对象名称,从 5 中减去现有数据子集的值。

clientdata$Burn1_r   <- 5 - clientdata$Burn1.
clientdata$Burn2_r   <- 5 - clientdata$Burn2
clientdata$Forw2_r   <- 5 - clientdata$Forw2
clientdata$Harm1_r   <- 5 - clientdata$Harm1
clientdata$Innov1_r   <- 5 - clientdata$Innov1

输出应该是

> clientdata$Burn1_r
[1] -1 -2 -2 -2 -3 -3 -3 ...
> clientdata$Burn2_r
[1] -3 -2 -2 -3 -3 -3 -3 ...
> clientdata$Forw2_r
[1] -2 -2 -2 -2 -1 -2 -2 ...
> clientdata$Harm1_r
[1] -3 -3 -3 -3 -2 -3 -3 ...
> clientdata$Innov1_r
[1] -2 -2 -2 -2 -1 -1 -2 ...

这样更清楚吗?很抱歉模棱两可,不擅长寻求帮助。

【问题讨论】:

  • 您能否展示一些示例数据集和您的预期输出
  • 最近使用assign()的人有很多问题。我不明白。但是在 R 中,你应该尽量避免它。在列表或向量中收集相关值几乎总是比将它们分配给当前环境中的一堆不同变量更有意义。
  • 当项目在列表中时,您可以使用data[[paste0(as.character(names[i]),"_new")]] 获取带有字符串的列表中的值。
  • 我已经搜索过了,相信我,我还不太擅长在 Google 中搜索“r”,一定有我遗漏的技巧。为什么assign() 不适用于“data$name”格式,但适用于“name”?另外,Flick 先生,虽然我很欣赏我是新来的,并且重复对 mod 来说很烦人,但您的评论没有链接到任何相关线程。你介意更新它吗,如果不是像我这样从谷歌搜索中找到这个但很难找到其他人的菜鸟。 EDIT* 刚刚收到您的更新,感谢您的代码,我会做更多的研究来完成这项工作。我为这个骗局道歉。

标签: r string loops assign


【解决方案1】:

这可以在没有assign 的情况下轻松完成,但如果这是为了理解assign 机制

curr.object <- paste(colnames(data), 'new', sep="_")
for(i in seq_along(curr.object)){
 assign('data', `[[<-`(data, curr.object[i], value=5-data[,i]))
 }
data
#   foo bar doo foo_new bar_new doo_new
#1   9  20   7      -4     -15      -2
#2  14  13   8      -9      -8      -3
#3   3   7  20       2      -2     -15
#4  18   2  12     -13       3      -7
#5   3   6  14       2      -1      -9

更新

以下是在数据集中创建变量的更复杂/间接/不寻常等方式。 IE。首先在全局环境中创建新变量,然后将其分配回数据集。

rev.items.new <- paste(colnames(clientdata), 'r', sep="_")
rev.items.new
#[1] "Burn1_r"  "Burn2_r"  "Harm1_r"  "Innov1_r"
for(i in seq_along(rev.items.new)){
 assign(rev.items.new[i], 5-clientdata[,i])
}

head(Burn1_r)
#[1] 1 2 2 2 3 3

clientdata[rev.items.new] <- mget(rev.items.new)
head(clientdata)
#    Burn1 Burn2 Harm1 Innov1 Burn1_r Burn2_r Harm1_r Innov1_r
#1     4     2     2      3       1       3       3        2
#2     3     3     2      3       2       2       3        2
#3     3     3     2      3       2       2       3        2
#4     3     2     2      3       2       3       3        2
#5     2     2     3      4       3       3       2        1
#6     2     2     2      4       3       3       3        1

数据

set.seed(25)
data <- as.data.frame(matrix(sample(1:20, 5*3, replace=TRUE), ncol=3,
    dimnames=list(NULL, c('foo', 'bar', 'doo'))) )

clientdata <-  structure(list(Burn1 = c(4, 3, 3, 3, 2, 2, 2, 3, 2, 3, 2, 4, 
3, 2, 2, 2, 2, 3, 3, 3, 4, 3, 3, 2, 2, 2, 3, 3, 4, 2, 2, 2, 1, 
4, 2, 4, 2, 3, 3, 3, 4, 2, 4, 3, 3, 2, 3, 2, 2, 3, 4, 3, 3, 2, 
3, 3, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, 3), Burn2 = c(2, 3, 3, 2, 
2, 2, 2, 3, 3, 4, 2, 3, 3, 2, 3, 3, 3, 3, 4, 3, 3, 4, 3, 2, 2, 
2, 2, 4, 3, 2, 4, 2, 3, 3, 3, 4, 3, 3, 2, 2, 4, 2, 3, 2, 2, 2, 
3, 2, 3, 3, 4, 3, 3, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3
), Forw2 = c(3, 3, 3, 3, 3, 4, 3, 3, 3, 4, 4, 3, 4, 3, 3, 3, 
4, 3, 3, 3, 4, 2, 3, 2, 2, 2, 4, 4, 4, 2, 4, 3, 3, 4, 3, 4, 3, 
2, 4, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 3, 4, 3, 4, 2, 3, 3, 4, 2, 
3, 3, 3, 3, 3, 3, 4, 3, 3), Harm1 = c(2, 2, 2, 2, 3, 2, 2, 2, 
2, 4, 2, 3, 4, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 4, 1, 2, 
2, 2, 1, 1, 2, 2, 4, 3, 3, 2, 4, 1, 3, 2, 3, 2, 2, 2, 2, 2, 2, 
4, 2, 3, 2, 3, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 2), Innov1 = c(3, 
3, 3, 3, 4, 4, 3, 2, 3, 4, 4, 3, 4, 3, 4, 4, 4, 3, 4, 3, 4, 2, 
3, 2, 3, 3, 4, 4, 4, 2, 4, 3, 1, 4, 4, 3, 3, 3, 4, 4, 4, 3, 1, 
4, 3, 3, 4, 3, 2, 3, 3, 2, 4, 2, 3, 1, 4, 2, 3, 2, 3, 1, 4, 3, 
3, 4, 2)), row.names = c(NA, -67L), .Names = c("Burn1", "Burn2", 
"Forw2", "Harm1", "Innov1"), class = "data.frame")

【讨论】:

  • @Alex 正如我之前提到的,您应该提供一些示例数据和预期结果。根据显示的代码,您似乎正在寻找这个。还有,用$也不是什么好主意,改用[,也就是我做的
  • 编辑了我的原件,再次感谢它的星期五 arvo,我真的很困扰。
  • @Alex 我在你的原文中找不到任何编辑
  • 重做对不起,主要是强调和犯错误。请立即查看编辑
  • @Alex 如果我理解您的新示例,这里的操作方式相同,只是替换名称
猜你喜欢
  • 2012-10-24
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2016-02-26
  • 1970-01-01
  • 2011-07-12
  • 2020-08-10
相关资源
最近更新 更多