变量名称不会更改:评估字符串,另存为数据框变量

时间:2018-07-12 16:54:06

标签: r

tldr版本:我不能重命名第三个变量。这是dput信息:

> dput(head(transfer))
structure(list(pxcor = c(0, 1, 2, 3, 4, 5), pycor = c(0, 0, 0, 
0, 0, 0), boarTerritoryStrength = structure(list(`count boars-here` = c(1.74067061418327, 
1.72108894667326, 1.80564895320475, 1.86442162955961, 1.96794014517206, 
1.97282628219563)), row.names = c(NA, 6L), class = "data.frame")), row.names = c(NA, 
6L), class = "data.frame")

该过程很重要:

我正在尝试评估一个长度可变的问题,例如

(bh +
(b1 - bh) * (1 / 4) +
(b2 - b1) * (1 / 8) +
(b3 - b2) * (1 / 16) +
(b4 - b3) * (1 / 32) +
(b5 - b4) * (1 / 64))

bh至bn是数据框列。我在这里找到了一个不错的衰减函数

decind <- function(rate, index){
  iv = 1:index
  rate^iv
}

我尝试了使用purrr::pmap的许多不同方式,但是无法使其正常工作。所以我回到了我所知道的,生成文本并评估该文本的地方。

我以数据框的形式获得了所需的计数:

inRadius <- RNetLogo::NLGetPatches(c(coord,radius_list), patchset = "patches", as.data.frame=TRUE, nl.obj = nl.object)

返回这样的数据帧(仅大得多):

pxcor = c(0,1,2,3,4,5)
pycor = c(0,0,0,0,0,0)
'count boars-here' = c(0,0,0,0,0,0)
'count boars in-radius 1' = c(0,0,0,0,0,0)
'count boars in-radius 2' = c(1,0,0,0,0,0)
'count boars in-radius 3' = c(1,1,1,0,1,1)

inRadius <- data.frame(pxcor, pycor, 'count boars-here', 'count boars in-radius 1', 'count boars in-radius 2', 'count boars in-radius 3')

在上面的数学公式中count boars-here = bh,依此类推...

我创建了一个衰减向量,将差乘以:

decay_index <- c(1,decind(rate = decay_rate,index = 3))

然后我创建差异的左侧,不包括bh

txt2 <- paste0("inRadius[",4:(r+3),"]")

和右侧:

txt3 <- paste0("inRadius[",3:(r+2),"]")

我通过位置而不是名称来引用它们,因为RNetLogo返回的名称不是理想的名称(例如count boars in-radius 1),并且我尝试使用dplyr::rename的尝试在生成的字符串中均未成功重命名的变量。

将左右两边放在一起:

txt4 <- paste0("(",txt2, " - ", txt3,") * ",decay_index[2:length(decay_index)], collapse=" + ")

添加bh

txt5 <- paste0("inRadius$boarTerritoryStrength <- inRadius[3] + ",txt4, collapse = " + ")

解析和评估:

inRadius$boarTerritoryStrength <- eval(parse(text = txt5))

这是我无法解决的地方。尽管我可以引用inRadius$boarTerritoryStrength,但我无法将标题名称从boarTerritoryStrength.count boars-here更改为{ {1}}即使boarTerritoryStrength返回names(inRadius)。怎么了?我认为这与变量的结构有关。当我将数据框缩小为感兴趣的变量时:

boarTerritoryStrength

并尝试重命名变量,我得到以下结果:

transfer <- inRadius[c("pxcor","pycor",'boarTerritoryStrength')]

仅使用transfer <- dplyr::rename(transfer,boarTerritoryStrength = transfer[3]) Error: `boarTerritoryStrength` = structure(list(boarTerritoryStrength = structure(list("count boars-here" = c(1.74067061418327, 1.72108894667326, 1.80564895320475, 1.86442162955961, 1.96794014517206, 1.97282628219563, 2.11644489282094, 2.23824464253994, 2.12110353045762, 2.0650885226467, 2.02798126531457, 2.05337715935252, 1.83241273580251, 1.94819393076716, 1.76530065423594, 1.49416173465329, 1.39802937920689, 1.24575433483398, 1.02206903695543, 0.853445962044646, 0.727744313331528, 0.677242963610581, 0.629207842090238, 0.649596808294064, 0.620633145981629, 0.709581297612886, 0.745212648875281, 0.846167659588047, 0.896615085966402, 0.962433665031823, 1.09757092198464, 1.04520982017658, 1.17204722990454, 1.24543078399972, 1.19204696623251, 1.20628338618684, 1.20454807527722, 1.11692787493013, 1.03415111931798, 1.06042889007006, 1.01173626271344, 1.00307658417938, 1.03234089328043, 1.06212347737113, 1.15538285142299, 1.25632927295749, 1.35198259473356, 1.59989035012643, 1.6 进行暴力破解就不会更改显示的名称。

回应r2evans

names(transfer)[3] <- 'boarTerritoryStrength'

2 个答案:

答案 0 :(得分:2)

为此,我不容忍使用eval(parse())。因此,这里不是解决原始问题的好办法,而是让您陷入困境:

DF <- data.frame(bh = 1:2, b1 = 3:4, b2 = 5:6)

with(DF, 
     bh +
       (b1 - bh) * (1 / 4) +
       (b2 - b1) * (1 / 8) 
)
#[1] 1.75 2.75

#programmatically, using matrix algebra
m <- as.matrix(DF)
m %*% c(1, (1/2 ^ (seq_len(ncol(m) - 1) + 1))) -
  m[, -ncol(m)] %*% (1/2 ^ (seq_len(ncol(m) - 1) + 1))
#     [,1]
#[1,] 1.75
#[2,] 2.75

答案 1 :(得分:1)

您的问题是transfer的第三列不是法线向量,而是嵌入式data.frame

transfer[[3]]
#   count boars-here
# 1         1.740671
# 2         1.721089
# 3         1.805649
# 4         1.864422
# 5         1.967940
# 6         1.972826

(对于“正常”框架,[[3]]将返回矢量,而不是框架。尝试mtcars[[3]]进行查看。)

有几种方法可以摆脱这种情况。如果这种情况经常发生,您可能希望以编程的方式更“合适”一些东西,但是只需快速解决:

transfer[[3]] <- transfer[[3]][[1]]
transfer
#   pxcor pycor boarTerritoryStrength
# 1     0     0              1.740671
# 2     1     0              1.721089
# 3     2     0              1.805649
# 4     3     0              1.864422
# 5     4     0              1.967940
# 6     5     0              1.972826
names(transfer)[3] <- 'boarTerritoryStrength'
transfer
#   pxcor pycor boarTerritoryStrength
# 1     0     0              1.740671
# 2     1     0              1.721089
# 3     2     0              1.805649
# 4     3     0              1.864422
# 5     4     0              1.967940
# 6     5     0              1.972826