【问题标题】:populate some of the rows in a data frame using the other column使用另一列填充数据框中的某些行
【发布时间】:2018-05-08 01:42:51
【问题描述】:

我正在尝试填充列 size,其值为 0。新值应该是列 name 的最后一段。我尝试了很多方法,但不知何故,当我试图只用 0 填充行时,它不会返回正确的值:

样本数据:

vertices=data.frame(name=c("a","b","c","a.b","a.c","a.a.9","a.b.8"),size= c(1,5,6,2,6,0,0))

ID name size
1     a    1
2     b    5
3     c    6
4   a.b    2
5   a.c    6
6 a.a.9    0
7 a.b.8    0

这条线按预期工作,除了我不想触摸不是 size=0 的行:

vertices$size <- sub(".*\\.", "", vertices$name)

ID name size
1     a    a
2     b    b
3     c    c
4   a.b    b
5   a.c    c
6 a.a.9    9
7 a.b.8    8

并且在代码中添加条件时,返回错误的结果:

vertices$size[vertices$size==0] <- sub(".*\\.", "", vertices$name)

ID name size
1     a    1
2     b    5
3     c    6
4   a.b    2
5   a.c    6
6 a.a.9    a
7 a.b.8    b

最后两行应该是 9 和 8。我该如何解决这个问题?

【问题讨论】:

    标签: r regex dataframe


    【解决方案1】:

    我们甚至需要对 name 进行子集化

    vertices$size[vertices$size==0]<- sub(".*\\.", "", vertices$name[vertices$size==0])
    
    vertices
    #   name size
    #1     a    1
    #2     b    5
    #3     c    6
    #4   a.b    2
    #5   a.c    6
    #6 a.a.9    9
    #7 a.b.8    8
    

    或者你也可以使用ifelse 具有相同的效果

    vertices$size <- ifelse(vertices$size == 0, sub(".*\\.", "", vertices$name), 
                                                vertices$name)
    

    正如@Frank 在 cmets size 中提到的那样,由于正则表达式方法,它的类从数字更改为字符。

    sub(".*\\.", "", vertices$name[vertices$size==0])
    #[1] "9" "8"
    

    如果我们需要维护size 列的类,我们可以使用as.numeric

    as.numeric(sub(".*\\.", "", vertices$name[vertices$size==0]))
    #[1] 9 8
    

    但是,这再次假设 size = 0 最后一个字符是一个数字,如果它是一个字符,它将返回 NA

    【讨论】:

    • 如果您决定将其作为答案发布,如何从评论中删除它
    • size 以数字开头,我猜在这里被强制转换为字符串。使用 data.table 的另一个很好的理由,它会发出警告,然后将字符强制转换为数字,而不是相反...
    • @Frank 使用正则表达式可以做到这一点。我们总是可以用as.numeric 包装它来维护类。我会更新答案。
    【解决方案2】:

    看起来您正在尝试保存大小错误的矢量。在最后一行你可能只是想要

    vertices$size[vertices$size==0] <- sub(".*\\.", "", vertices$name[vertices$size==0]) 
    

    您缺少 RHS 上的条件。

    你在最后两个位置得到“a”和“b”,因为它只取向量的前两个元素(在你的例子中是所有名称的子元素)。

    【讨论】:

      【解决方案3】:

      使用stringrdplyr

      vertices %>% mutate(size = ifelse(size > 0, size, str_extract(name, "[0-9]+")))
      

      【讨论】:

        【解决方案4】:

        我们也可以使用regmatches/regexpr

        vertices$size[!vertices$size] <- 
            as.numeric(regmatches(vertices$name, regexpr("\\d+$", vertices$name)))
        
        vertices
        #   name size
        #1     a    1
        #2     b    5
        #3     c    6
        #4   a.b    2
        #5   a.c    6
        #6 a.a.9    9
        #7 a.b.8    8
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-12-08
          • 1970-01-01
          • 2019-01-21
          • 2016-02-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-26
          相关资源
          最近更新 更多