【问题标题】:Extract one element from each row从每一行中提取一个元素
【发布时间】:2014-09-29 17:39:34
【问题描述】:

在R中,我有一个如下的数据框

    J   HE  JUS     HEUS
1   0   0   J-US    0
2   0   0   J-US    0
3   J   0   0       0
4   J   0   0       0
5   0   HE  0       0
6   0   0   0       HE-US
7   0   0   0       0

我想将其缩小为 1 列,如下所示

1  J-US
2  J-US
3  J
4  J
5  HE
6  HE-US
7  0

即检查每一行并提取非零元素,如果没有非零元素则使用0。

【问题讨论】:

  • 如果一行中有多个非零元素怎么办?

标签: r


【解决方案1】:

这是使用which.max的另一种方式

apply(d, 1, function(x) x[which.max(x != '0')])
#       1       2       3       4       5       6       7 
#  "J-US"  "J-US"     "J"     "J"    "HE" "HE-US"     "0" 

【讨论】:

    【解决方案2】:

    或者你可以这样做:

      df[cbind(1:nrow(df), max.col(df!=0, "first"))]
      #[1] "J-US"  "J-US"  "J"     "J"     "HE"    "HE-US" "0" 
    

    数据

    df <- structure(list(J = c("0", "0", "J", "J", "0", "0", "0"), HE = c("0", 
    "0", "0", "0", "HE", "0", "0"), JUS = c("J-US", "J-US", "0", 
    "0", "0", "0", "0"), HEUS = c("0", "0", "0", "0", "0", "HE-US", 
    "0")), .Names = c("J", "HE", "JUS", "HEUS"), class = "data.frame", row.names = c("1", 
    "2", "3", "4", "5", "6", "7"))
    

    【讨论】:

      【解决方案3】:

      您可以使用ifelse 检查所有内容是否为 0 并相应地提取值:

      data.frame(x=apply(dat, 1, function(x) ifelse(all(x == "0"), "0", head(x[x!="0"], 1))))
      #       x
      # 1  J-US
      # 2  J-US
      # 3     J
      # 4     J
      # 5    HE
      # 6 HE-US
      # 7     0
      

      【讨论】:

      • 非常感谢!工作完美!
      【解决方案4】:

      另一个使用粘贴的矢量化选项:

      xx <-gsub("0| ","",do.call(paste,dat))
      1] "J-US"  "J-US"  "J"     "J"     "HE"    "HE-US" ""  
      

      请注意,如果您连续只有零,您会得到空字符。这比“0”更符合逻辑。 如果您想用“0”替换空字符:

      xx[nzchar(xx)==0] <- "0"
      [1] "J-US"  "J-US"  "J"     "J"     "HE"    "HE-US" "0"
      

      还要注意,即使您连续有多个非零元素,此答案也将起作用。

      【讨论】:

        【解决方案5】:

        另一种矢量化解决方案:

        w <- which(dne <- df != 0, arr.ind = TRUE)
        unname(ifelse(rowSums(dne), df[w[order(rownames(w)),]], 0))
        # [1] "J-US"  "J-US"  "J"     "J"     "HE"    "HE-US" "0"    
        

        或者这样做可能更容易

        rs <- unname(rowSums(df != 0))
        ifelse(rs != 0, t(df)[t(df) != 0], rs[rs == 0])
        # [1] "J-US"  "J-US"  "J"     "J"     "HE"    "HE-US" "0"   
        

        【讨论】:

          猜你喜欢
          • 2021-01-16
          • 2017-10-10
          • 2018-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多