查找值更改时的列名

时间:2018-11-13 09:13:05

标签: r datatable

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

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

如何为每一行实现这一目标?

3 个答案:

答案 0 :(得分:2)

向量化的方式是

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

此外,您可以将apply与边距1一起使用(进行行操作),并找到diff不为0的第一个索引,即

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

一种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.