【问题标题】:How to repetitively replace substrings in variables in R如何重复替换R中变量中的子字符串
【发布时间】:2013-10-13 16:32:10
【问题描述】:

我有以下任务

Treatment$V010 <- as.numeric(substr(Treatment$V010,1,2))
Treatment$V020 <- as.numeric(substr(Treatment$V020,1,2))
[...]
Treatment$V1000 <- as.numeric(substr(Treatment$V1000,1,2))

我有 100 个变量,从 $V010、$V020、$V030... 到 $V1000。这些是不同长度的数字。我想只“提取”数字的前两位数字,并将旧数字替换为两位长的新数字。

我的数据框“Treatment”还有 80 个变量,我在这里没有提到,所以我的目标是这个函数只应用于提到的 100 个变量。

我该怎么做?我可以编写该命令 100 次,但我确信有更好的解决方案。

【问题讨论】:

    标签: r loops substring repeat


    【解决方案1】:

    好吧,让我们开始吧。首先要做的事情:当您想要获取数据框的特定列时,您需要指定它们的名称来访问它们:

    cnames = paste0('V',formatC(seq(10,1000,by=10), width = 3, format = "d", flag = "0"))
    

    (cnames是一个包含c('V010','V020', ..., 'V1000')的向量)

    接下来,我们将获取它们的索引:

    coli=unlist(sapply(cnames, function (x) which(colnames(Treatment)==x)))
    

    coli 是一个向量,包含相关列的Treatment 中的索引)

    最后,我们会将您的函数应用于这些列:

    Treatment[coli] = mapply(function (x) as.numeric(substr(x, 1, 2)), Treatment[coli])
    

    有效吗?

    PS:如果有人有更好/更简洁的方法,请告诉我:)

    编辑

    中间步骤没有用,因为您已经可以使用列名cnames 来获取相关列,即

    Treatment[cnames] = mapply(function (x) as.numeric(substr(x, 1, 2)), Treatment[cnames])
    

    (将列名转换为列索引的唯一好处是当数据框中缺少一些列时 - 在这种情况下,Treatment['non existing column']undefined columns selected 一起崩溃)

    【讨论】:

    • 广泛而美好!不过,我认为,可以直接使用 Treatment[cnames] 而不是 coli 方法,因为 Treatment 已经有了名称。然后,_ply 工作。
    【解决方案2】:

    根据可以用正则表达式描述的模式选择相关列的解决方案。

    正则表达式解释:
    ^:字符串开头
    V:字面V
    \\d{2}:正好2位

    Treatment <- data.frame(V010 = c(120, 130), x010 = c(120, 130), xV1000 = c(111, 222), V1000 = c(111, 222))
    Treatment
    #   V010 x010 xV1000 V1000
    # 1  120  120    111   111
    # 2  130  130    222   222
    
    # columns with a name that matches the pattern (logical vector)
    idx <- grepl(x = names(Treatment), pattern = "^V\\d{2}")
    
    # substr the relevant columns
    Treatment[ , idx] <- sapply(Treatment[ , idx], FUN = function(x){
      as.numeric(substr(x, 1, 2))
      })
    
    Treatment
    #   V010 x010 xV1000 V1000
    # 1   12  120    111    11
    # 2   13  130    222    22
    

    【讨论】:

    • 好吧,OP 的既定目标是替换 Treatment$V010(及以下)的内容,而不是列的名称......
    • 啊……谢谢@Jealie,我误读了这个问题……我会编辑我的答案。
    猜你喜欢
    • 2015-12-21
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 2014-11-05
    • 2022-01-07
    • 2013-05-18
    • 2021-08-03
    • 1970-01-01
    相关资源
    最近更新 更多