【问题标题】:Find column name at change of value在值变化时查找列名
【发布时间】:2018-11-13 09:13:04
【问题描述】:

我有一个这样的数据集(可重现)

X1 <- c(0,0,1,3)
X2 <- c(0,0,4,5)
X3 <- c(0,2,2,6)
X4 <- c(0,0,0,1)

df <- data.frame(rbind(X1, X2, X3, X4))
rownames(df) <- NULL
df

  X1 X2 X3 X4
1  0  0  1  3
2  0  0  4  5
3  0  2  2  6
4  0  0  0  1

我想添加一个列,它将采用列名的值,其中每行的值从 0 更改为大于 0 的任何值

因此预期的输出是

  X1 X2 X3 X4 Value
1  0  0  1  3    X3
2  0  0  4  5    X3
3  0  2  2  6    X2
4  0  0  1  1    X4

如何为每一行实现这一点?

【问题讨论】:

标签: r datatable


【解决方案1】:

矢量化的方法是,

names(df)[max.col(df != 0, ties.method = 'first')]
#[1] "X3" "X3" "X2" "X4"

另外,你可以使用margin为1的apply(做行操作),找到diff不为0的第一个索引,即

names(df)[apply(df, 1, function(i) which(diff(i) != 0)[1]) + 1]
#[1] "X3" "X3" "X2" "X4"

【讨论】:

  • 矢量化方式是一个不错的选择。
【解决方案2】:

再次使用apply 的另一个选项:

names(df)[apply(df, 1, function(x) which(x > 0)[1])]
# [1] "X3" "X3" "X2" "X4"

【讨论】:

    【解决方案3】:

    tidyverse 解决方案:

    df %>%
      rowid_to_column() %>% #Creating an ID
      gather(var, val, -rowid) %>% #Transforming the data from wide to long
      arrange(rowid) %>% #Arranging according ID
      group_by(rowid) %>% #Grouping by ID
      mutate(res = ifelse(cumsum(val) > 0, paste0(var), NA)) %>% #Applying the condition
      filter(res == first(res[!is.na(res)])) %>% #Selecting the relevant value
      left_join(df %>% rowid_to_column(), by = c("rowid" = "rowid")) %>% #Joining with the original df
      ungroup() %>% 
      select(-rowid, -var, -val) #Deleting the redundant variables
    
      res      X1    X2    X3    X4
      <chr> <dbl> <dbl> <dbl> <dbl>
    1 X3       0.    0.    1.    3.
    2 X3       0.    0.    4.    5.
    3 X2       0.    2.    2.    6.
    4 X4       0.    0.    0.    1.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-03
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 2022-10-12
      相关资源
      最近更新 更多