【问题标题】:How to extract an unique element according a set of prefered conditions如何根据一组首选条件提取唯一元素
【发布时间】:2017-01-29 21:25:46
【问题描述】:

以数据框 df,我想根据每个 的以下首选条件提取 unique value字段:

1-如果存在C1,则提取相应的值并忽略其他值

2-如果存在C2,则提取相应的值并忽略其他值

...等等直到C5

数据:

df <- data.frame (Field=rep(c("F1","F2","F3","F4","F5"),each=3),
              Cond=rep(c("C1","C2","C3","C4","C5"),3),
              Value=c(1:15))

想要的输出:

output <-  data.frame (F= c("F1","F2","F3","F4","F5"),
                   C= c("C1","C1","C2","C1","C3"),
                   Value= c(1,6,7,11,13))

(注1:值仅设置为示例,真实数据值没有排序)

(注2:真正的条件列根本没有按字母顺序排列。我的想法是,如果 A 存在而不是选择“A 值”,否则传递到下一个条件“如果B存在...”等)

【问题讨论】:

  • 可以假设C 中的值已排序吗?
  • @Roman,不......这些值只是为了举例说明而设置的

标签: r dataframe extract data-extraction


【解决方案1】:

如果您可以在处理之前对 data.frame 进行排序,这相当容易。请注意,这适用于这种特殊情况。如果您的 Cond 值发生变化,字母排序可能会失效。

library(dplyr)
df <- data.frame (Field=rep(c("F1","F2","F3","F4","F5"),each=3),
                  Cond=rep(c("C1","C2","C3","C4","C5"),3),
                  Value=c(1:15))

df <- df[with(df, order(Field, Cond)), ]
res <- df %>%
  group_by(Field) %>%
  filter(row_number() == 1)

Source: local data frame [5 x 3]
Groups: Field [5]

   Field   Cond Value
  <fctr> <fctr> <int>
1     F1     C1     1
2     F2     C1     6
3     F3     C2     7
4     F4     C1    11
5     F5     C3    13

这是另一种更通用的方法。排序顺序在so 中定义(参见this question)。请注意我是如何弄乱Cond 的值以显示它没有按字母顺序排序的。

df <- data.frame (Field=rep(c("F1","F2","F3","F4","F5"),each=3),
                  Cond=rep(c("rg1","kl2","xy3","rq4","ab5"),3),
                  Value=c(1:15))

so <- c("rg1","kl2","xy3","rq4","ab5")

df %>%
  group_by(Field) %>%
  slice(match(so, Cond)) %>%
  filter(row_number() == 1)

   Field   Cond Value
  <fctr> <fctr> <int>
1     F1    rg1     1
2     F2    rg1     6
3     F3    kl2     7
4     F4    rg1    11
5     F5    xy3    13

【讨论】:

  • 确实你是对的,我认为那会是个问题。我的“条件”列根本没有按字母顺序排列。我的想法是,如果 A 存在而不是选择“A 值”,否则传递到下一个条件“如果 B 存在......”等等
  • @Rui 我修改了我的答案,我认为它现在应该适用于您的一般情况。
【解决方案2】:

另一个选项是使用data.table

library(data.table)
setDT(df)[order(Field, Cond), head(.SD, 1), by = Field]
#    Field Cond Value
#1:    F1   C1     1
#2:    F2   C1     6
#3:    F3   C2     7
#4:    F4   C1    11
#5:    F5   C3    13

【讨论】:

  • 是的,如果要按字母顺序对“Cond”进行排序,它确实有效。但是,如果“排序”列未按字母顺序排序,则该示例将不起作用。
  • @Rui 在这种情况下,将其转换为factor 并按照您想要的顺序指定levels order(Field, factor(Cond, levels = lvl))
猜你喜欢
  • 1970-01-01
  • 2015-07-01
  • 2019-04-15
  • 2023-03-06
  • 2014-09-14
  • 2015-08-30
  • 1970-01-01
  • 2022-12-04
  • 1970-01-01
相关资源
最近更新 更多