R中的colnames()函数 - 将表值作为独立对象/变量处理

时间:2017-09-05 16:37:49

标签: r loops object instance-variables

我有一个值列表,我希望将其用作从特定网站上的单独网址中删除的单独表格的名称。

> Fac_table
[[1]]
[1] "fulltime_fac_table"

[[2]]
[1] "parttime_fac_table"

[[3]]
[1] "honorary_fac_table"

[[4]]
[1] "retired_fac_table"

我想遍历列表以自动生成具有相应名称的4个表。

结果应如下所示:

> fulltime_fac_table
    職稱          
V1  "教授兼系主任"
V2  "教授"        
V3  "教授"        
V4  "教授"        
V5  "特聘教授"    

> parttime_fac_table
    職稱       姓名    
V1  "教授"     "XXX"
V2  "教授"     "XXX"
V3  "教授"     "XXX"
V4  "教授"     "XXX"
V5  "教授"     "XXX"
V6  "教授"     "XXX"

我有另一个名为“headers”的列表,其中包含在线各个表的列标题。

> headers
[[1]]
[1] "職稱"             "姓名"             "    研究領域"
[4] "聯絡方式"        

[[2]]
[1] "職稱"     "姓名"     "研究領域" "聯絡方式"

我能够使用以下代码为各个表分配值:

> assign(eval(parse(text="Fac_table[[i]]")), as_tibble(matrix(fac_data,
> nrow = length(headers[[i]])))

这会产生一个填充表,没有列标题,如下所示:

> honorary_fac_table
    [,1]       [,2]    
V1  "名譽教授" "XXX"
V2  "名譽教授" "XXX"
V3  "名譽教授" "XXX"
V4  "名譽教授" "XXX"

但是无法为每个表分配列名。

以下代码均无效:

> assign(colnames(eval(parse(text="Fac_table[1]"))), c(gsub("\\s", "", headers[[1]])))
Error in assign(colnames(eval(parse(text = "Fac_table[1]"))), c(gsub("\\s",  : 
  第一個引數不正確

> colnames(eval(parse(text="Fac_table[i]"))) <- c(gsub("\\s", "", headers[[i]]))
Error in colnames(eval(parse(text = "Fac_table[i]"))) <- c(gsub("\\s",  : 
  賦值目標擴充到非語言的物件

> do.call("<-", colnames(eval(parse(text="Fac_table[i]"))), c(gsub("\\s", "", headers[[i]])))
Error in do.call("<-", colnames(eval(parse(text = "Fac_table[i]"))), c(gsub("\\s",  : 
  second argument must be a list

为了简化问题,一个可重现的例子如下:

> varNamelist <- list(c("tbl1","tbl2","tbl3","tbl4"))
> colHeaderlist <- list(c("col1","col2","col3","col4"))
> tableData <- matrix([1:12], ncol=4)

这有效:

> assign(eval(parse(text="varNamelist[[1]][1]")), matrix(tableData, ncol
> = length(colHeaderlist[[1]])))

但这不是:

> colnames(as.name(varNamelist[[1]][1])) <- colHeaderlist[[1]]
Error in `colnames<-`(`*tmp*`, value = c("col1", "col2", "col3", "col4" : 
  attempt to set 'colnames' on an object with less than two dimensions

似乎R中的colnames()函数无法将“Fac_table [i]”表示的字符串视为变量名,其中可以存储独立数据(与Fac_table分开)。

> colnames(as.name(Fac_table[[1]])) <- headers[[1]]
Error in `colnames<-`(`*tmp*`, value = c("a", "b", "c",  : 
  attempt to set 'colnames' on an object with less than two dimensions

直接替换'fulltime_fac_table'可以正常工作。

> colnames(fulltime_fac_table) <- headers[[1]]

有没有解决这个问题的方法?

谢谢!

2 个答案:

答案 0 :(得分:0)

有一个解决方案,但我认为如果我理解正确,目前的设置可能比必要的更复杂。所以我会尝试让这项工作变得更容易。

如果您正在使用一维数据,我建议您使用向量,因为它们比列表更适合此目的。因此,对于这个项目,我首先要存储表和标题的名称,如下所示:

varNamelist <- c("tbl1","tbl2","tbl3","tbl4")
colHeaderlist <- c("col1","col2","col3","col4")

仍然很难确定这些表的输入的数据格式和来源是什么来自您的问题,但一般来说,有时数据框可以比矩阵更容易使用,只要你没有使用大数据。对于这些步骤,分配功能通常也不是必需的。相反,在设置数据帧时,我们可以同时应用数据框的名称,列的名称和数据内容,如下所示:

tbl1 <- data.frame("col1"=c(1,2,3),
                   "col2"=c(4,5,6),
                   "col3"=c(7,8,9),
                   "col4"=c(10,11,12))

同样,我们使用c()而不是list()标注的向量来填充每列,因为每列都是它自己的单维。

要检查tbl1的输出,我们可以使用print():

print(tbl1)

  col1 col2 col3 col4
1    1    4    7   10
2    2    5    8   11
3    3    6    9   12

如果它是一个选项来创建更接近这种方式的表格,那么这可能比使用这么多列表和分配函数更容易;很快变得过于复杂。

但是如果你想在最后将所有表存储在一个地方,你可以把它们放在一个列表中:

tableList <– list(tbl1=tbl1,tbl2=tbl2,tbl3=tbl3,tbl4=tbl4)

str(tableList)
List of 4
 $ tbl1:'data.frame':   3 obs. of  4 variables:
  ..$ col1: num [1:3] 1 2 3
  ..$ col2: num [1:3] 4 5 6
  ..$ col3: num [1:3] 7 8 9
  ..$ col4: num [1:3] 10 11 12
 $ tbl2:'data.frame':   3 obs. of  4 variables:
  ..$ col1: num [1:3] 1 2 3
  ..$ col2: num [1:3] 4 5 6
  ..$ col3: num [1:3] 7 8 9
  ..$ col4: num [1:3] 10 11 12
 $ tbl3:'data.frame':   3 obs. of  4 variables:
  ..$ col1: num [1:3] 1 2 3
  ..$ col2: num [1:3] 4 5 6
  ..$ col3: num [1:3] 7 8 9
  ..$ col4: num [1:3] 10 11 12
 $ tbl4:'data.frame':   3 obs. of  4 variables:
  ..$ col1: num [1:3] 1 2 3
  ..$ col2: num [1:3] 4 5 6
  ..$ col3: num [1:3] 7 8 9
  ..$ col4: num [1:3] 10 11 12

答案 1 :(得分:0)

根据此代码提供的@ Ryan建议,我找到了解决方案:

for (i in seq_along(url)){

  webpage <- read_html(url[i]) #loop through URL list to access html data

  fac_data <- html_nodes(webpage,'.tableunder')  %>% html_text()
  fac_data1 <- html_nodes(webpage,'.tableunder1')  %>% html_text()
  fac_data <- c(fac_data, fac_data1) #Store table data on each URL in a variable 

  x <- fac_data %>% matrix(ncol = length(headers[[i]]), byrow=TRUE) #make matrix to extract column data

  for (j in seq_along(headers[[i]])){
    y <- cbind(x[,j]) #extract column data and store in temporary variable
    colnames(y) <- as.character(headers[[i]][j]) #add column name
    print(cbind(y)) #loop through headers list to print column data in sequence. ** cbind(y) will be overwritten when I try to store the result on a list with 'z <- cbind(y)'.
  }
}

我现在能够打印出所有值,并填写相关数据的标题。

已发布跟进问题here

final code也解决了这个问题。