【问题标题】:Why won't my column name change work in R?为什么我的列名更改在 R 中不起作用?
【发布时间】:2013-01-31 10:45:12
【问题描述】:

这是我编写的脚本的一部分,用于在使用merge() 后更充分地合并列。 如果两个数据集都有一个名称相同的列merge(),则为您提供column.xcolumn.y 列。
我已经编写了一个脚本来将这些数据放在一起并删除不需要的列(这将是column.ycolumn.x_error,我添加了一个列以在dat$column.x != dat$column.y) 的情况下发出警告。
我还想将column.x 重命名为column,以减少我的数据集中不需要的手动操作。我还没有设法将column.x 重命名为column,请参阅代码了解更多信息。

dat 是通过 dat = merge(data1,data2, by= "ID", all.x=TRUE) 获得的

#obtain a list of double columns
dubbelkol = cbind()
sorted = sort(names(dat))
for(i in as.numeric(1:length(names(dat)))) {
  if(grepl(".x",sorted[i])){
    if (grepl(".y", sorted[i+1]) && (sub(".x","",sorted[i])==sub(".y","",sorted[i+1]))){
      dubbelkol = cbind(dubbelkol,sorted[i],sorted[i+1])
    } 
  }  
}

#Check data, fill in NA in column.x from column.y if poss
temp = cbind()
for (p in as.numeric(1:(length(dubbelkol)-1))){
  if(grepl(".x",dubbelkol[p])){
    dat[dubbelkol[p]][is.na(dat[dubbelkol[p]])] = dat[dubbelkol[p+1]][is.na(dat[dubbelkol[p]])]
    temp = (dat[dubbelkol[p]] != dat[dubbelkol[p+1]])
    colnames(temp) = (paste(dubbelkol[p],"_error", sep=""))
    dat[colnames(temp)] = temp
  }
}
#If every value in "column.x_error" is TRUE or NA, delete "column.y" and "column.x_error"
#Rename "column.x" to "column"
#from here until next comment everything works
droplist= c()
for (k in as.numeric(1:length(names(dat)))) {
  if (grepl(".x_error",colnames(dat[k]))) {
    if (all(dat[k]==FALSE, na.rm = TRUE)) {
      droplist = c(droplist,colnames(dat[k]), sub(".x_error",".y",colnames(dat[k])))
#the next line doesnt work, it's supposed to turn the .x column back to "" before the .y     en .y_error columns are dropped.
      colnames(dat[sub(".x_error",".x",colnames(dat[k]))])= paste(sub(".x_error","",colnames(dat[k])))
    }
  }
}
dat = dat[,!names(dat) %in% droplist]

paste(sub(".x_error","",colnames(dat[k]))) 会给我"BNR" 就好了,但colnames(...) = ... 不会更改dat 中的列名。

知道出了什么问题吗?

data1
+----+-------+
| ID | BNR   | 
+----+-------+
|  1 | 123   | 
|  2 | 234   |
|  3 | NA    | 
|  4 | 456   | 
|  5 | 677   |
|  6 | NA    | 
+----+-------+

data2
+----+-------+
| ID | BNR   | 
+----+-------+
|  1 | 123   | 
|  2 | 234   |
|  3 | 345   | 
|  4 | 456   | 
|  5 | 677   |
|  6 | NA    | 
+----+-------+
dat
+----+-------+-------+-----------+
| ID | BNR.x | BNR.y |BNR.x_error|
+----+-------+-------+-----------+
|  1 | 123   | NA    |FALSE      |
|  2 | 234   | 234   |FALSE      |
|  3 | NA    | 345   |FALSE      |
|  4 | 456   | 456   |FALSE      |
|  5 | 677   | 677   |FALSE      |
|  6 | NA    | NA    |NA         |
+----+-------+-------+-----------+

desired output
+----+-------+
| ID | BNR   | 
+----+-------+
|  1 | 123   |
|  2 | 234   | 
|  3 | 345   | 
|  4 | 456   | 
|  5 | 677   | 
|  6 | NA    | 
+----+-------+

【问题讨论】:

  • 您能否提供一个示例数据,并解释您要做什么?
  • 你能否告诉我们你是如何获得dat的。我这样说是因为,可能有一种方法可以直接使用merge 或其他替代方法获得您的结果。当然,我会尝试找出您的代码中发生的情况。但以防万一您对替代品感兴趣。
  • 是的,更好更快的代码当然总是更好,我会添加完整的代码。我只使用 R 1 周,所以它可能还不是很好。
  • 很抱歉要求更多的东西,但你能告诉我们data1data2和你的desired output吗?这将使我们能够提供直截了当的结果,我猜你会想要更多(它会更短)。
  • 如果可以帮助我,添加更多信息绝不是问题。感谢您的宝贵时间。

标签: r rename


【解决方案1】:

我建议更换:

sub(".x_error",".x",colnames(dat[k]))]

与:

sub("\\.x_error", "\\.x", colnames(dat[k]))] 

如果您想替换实际的.。你必须用\\. 逃脱.。正则表达式中的. 表示any character

更好的是,既然您将 . 替换为 .,为什么不直接说:

sub("x_error", "x", colnames(dat[k]))] 

(或)如果除了x_error之外没有其他_error,那么简单:

sub("_error", "", colnames(dat[k]))] 

编辑:问题似乎是您的数据格式似乎正在加载左侧和右侧的其他列。您可以先选择所需的列,然后合并。

d1 <- read.table(textConnection("| ID | BNR   | 
|  1 | 123   | 
|  2 | 234   |
|  3 | NA    | 
|  4 | 456   | 
|  5 | 677   |
|  6 | NA    |"), sep = "|", header = TRUE, stringsAsFactors = FALSE)[,2:3]

d1$BNR <- as.numeric(d1$BNR)

d2 <- read.table(textConnection("|  1 | 123   | 
|  2 | 234   |
|  3 | 345   | 
|  4 | 456   | 
|  5 | 677   |
|  6 | NA    |"), header = FALSE, sep = "|", stringsAsFactors = FALSE)[,2:3]

names(d2) <- c("ID", "BNR")
d2$BNR <- as.numeric(d2$BNR)

# > d1
#   ID BNR
# 1  1 123
# 2  2 234
# 3  3  NA
# 4  4 456
# 5  5 677
# 6  6  NA

# > d2
#   ID BNR
# 1  1 123
# 2  2 234
# 3  3 345
# 4  4 456
# 5  5 677
# 6  6  NA

dat <- merge(d1, d2, by="ID", all=T)
> dat

#   ID BNR.x BNR.y
# 1  1   123   123
# 2  2   234   234
# 3  3    NA   345
# 4  4   456   456
# 5  5   677   677
# 6  6    NA    NA

# replace all NA values in x from y
dat$BNR.x <- ifelse(is.na(dat$BNR.x), dat$BNR.y, dat$BNR.x)

# now remove y
dat$BNR.y <- null

【讨论】:

  • 除非您检查grepl("\\.x_error, ...),否则您的第一个if 语句永远不会是TRUE
  • 我不知道如何,但它实际上是TRUE。从".x_error,...) 更改为"\\.x_error,...) 并没有改变ifsub 方法中的任何内容。
  • 嗯好吧,我想我犯了一个错误。很抱歉造成混乱。
  • 我刚刚意识到我在为这个问题提供随机信息时可能已经过火了。我想知道的是,非常简单,为什么colnames(dat[1]) = "newname" 不会将第 1 列的名称更改为新名称?包含“newname”或使用colnames(dat["oldname"] = "newname" 的变量也不起作用。
  • 这行不通。你应该这样做 colnames(dat)[1] &lt;- "newname" 或者如果你知道列号但名称,colnames(dat)[colnames(dat) == "oldname"] &lt;- "newname"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
  • 2014-10-25
  • 2012-04-21
  • 1970-01-01
  • 2017-10-23
  • 2021-12-05
  • 1970-01-01
相关资源
最近更新 更多