R:使用if条件编辑列值

时间:2014-06-27 07:30:36

标签: r

我有一个包含多个列的数据框。其中一个包含PEGID,如AEG1,AEG2,......,AEG50,HEG1,HEG2,...,HEG50,SEG1,SEG2,...,SEG50。因此,数据框有150行。现在我想只改变其中的一些Plotids,所以有AEG01,AEG02,...而不是AEG1,AEG2,......所以,我只想添加一个" 0"某些列条目。我通过使用lapply,for循环,编写函数来尝试它,但是没有任何工作。始终存在错误消息:

In if (nchar(as.character(dat_merge$EP_Plotid)) == 4)
paste(substr(dat_merge$EP_Plotid,  ... :
the condition has length > 1 and only the first element will be used

所以,这是我的最后一次尝试:

Plotid_func <- function(x) {
if(nchar(as.character(dat_merge$EP_Plotid))==4)
paste(substr(dat_merge$EP_Plotid, 1, 3), "0", substr(dat_merge$EP_Plotid, 4, 4), sep="")
}

dat_merge$Plotid <- sapply(dat_merge$EP_Plotid, Plotid_func)

因此,我想只选择那些带有四位数的列条目。仅对那些选定的条目,我想添加0。有谁能够帮我? dat_merge是我的数据框的名称,EP_Plotid是我要编辑的列。提前致谢

3 个答案:

答案 0 :(得分:1)

在数字部分使用sprintf后,只需提取“字符串”部分和“数字”部分并将它们粘贴在一起。

一个例子:

## "x" is the "column" of plot ids. Here I go up to 12
##    to demonstrate the zero padding that it sounds like
##    you're looking for
x <- c(paste0("AEG", 1:12), paste0("HEG", 1:12))

## Extract the string values
Strings <- gsub("([A-Z]+)(.*)", "\\1", x)

## Extract the numeric values
Nums <- gsub("([A-Z]+)(.*)", "\\2", x)

## Put them back together
paste0(Strings, sprintf("%02d", as.numeric(Nums)))
#  [1] "AEG01" "AEG02" "AEG03" "AEG04" "AEG05" "AEG06"
#  [7] "AEG07" "AEG08" "AEG09" "AEG10" "AEG11" "AEG12"
# [13] "HEG01" "HEG02" "HEG03" "HEG04" "HEG05" "HEG06"
# [19] "HEG07" "HEG08" "HEG09" "HEG10" "HEG11" "HEG12"

答案 1 :(得分:1)

或者您可以修改您的函数以实际使用输入变量x(原始函数中没有发生)

dat_merge <- data.frame(EP_Plotid = c("AEG1", "AEG2", "AEG50", "HEG1", "HEG2", "HEG50", "SEG1", "SEG2", "SEG50"))

Plotid_func <- function(x) {
  if(nchar(as.character(x)) == 4){
    paste(substr(x, 1, 3), "0", substr(x, 4, 4), sep="") 
  } else as.character(x)
}

dat_merge$Plotid <- sapply(dat_merge$EP_Plotid, Plotid_func)
dat_merge

#   EP_Plotid Plotid
# 1      AEG1  AEG01
# 2      AEG2  AEG02
# 3     AEG50  AEG50
# 4      HEG1  HEG01
# 5      HEG2  HEG02
# 6     HEG50  HEG50
# 7      SEG1  SEG01
# 8      SEG2  SEG02
# 9     SEG50  SEG50

你的函数的矢量化版本(比使用仅sapply循环的for要好得多)

dat_merge$Plotid <- ifelse(nchar(as.character(dat_merge$EP_Plotid))==4, paste(substr(dat_merge$EP_Plotid, 1, 3), "0", substr(dat_merge$EP_Plotid, 4, 4), sep=""), as.character(dat_merge$EP_Plotid))

答案 2 :(得分:0)

或者使用formatC与库中的str_extract的组合(stringr)

 library(stringr)
来自Ananda's帖子的

x。  分别提取字母和数字。  将0标记为具有formatC的数字  粘在一起

 paste0(str_extract(x, "[[:alpha:]]+"), formatC(as.numeric(str_extract(x,"\\d+")), width=2, flag=0))
 #[1] "AEG01" "AEG02" "AEG03" "AEG04" "AEG05" "AEG06" "AEG07" "AEG08" "AEG09"
 #[10] "AEG10" "AEG11" "AEG12" "HEG01" "HEG02" "HEG03" "HEG04" "HEG05" "HEG06"
 #[19] "HEG07" "HEG08" "HEG09" "HEG10" "HEG11" "HEG12"