【问题标题】:Compare multiple column of dataframe with condition R将数据框的多列与条件 R 进行比较
【发布时间】:2018-07-25 18:05:14
【问题描述】:

我有一个数据框(包含 200k 行):

DF1>

ID   SR1    SR2      DRC1   DX2
1    123    as#12.c  ABC-1  SXI
2    124    ae&14.v  ABC-1  SXI
3    125    at$19.e  AXX-1    
4    125    at$19.e  AXX-1  SCV
5    785    ab&22.n  AWZ-2  DDF
6    849    ab&22.n  AWZ-5  DDF

为此,我想根据以下条件将新列添加到DF1 为status:

  1. 检查每个DX2 值,我们在DRC-1 中具有相同的值(即对于ID 1 和2,我们具有与ABC-1 相同的DRC1 值)。
  2. 在某些情况下,我没有DX2 值,对于那些检查SR-1 和SR-2 来比较整个数据帧中的DRC-1 值,如果它在状态中显示True,否则False 相同。

注意:如果 SR-1 或 SR-2 中的任何值与整个数据帧中的任何行匹配,(即所需输出中的第 4 行)

  1. 我们没有DX2 值,但是当使用SR-1 和SR-2 比较日期框时,发现一些我们有DX2 值对应于SR-1 和SR-2 的地方比给出状态为True-ID 或 False-ID 视情况而定。

期望的输出:

ID   SR1    SR2      DRC1   DX2  Status
1    123    as#12.c  ABC-1  SXI  True
2    124    ae&14.v  ABC-1  SXI  True
3    125    at$19.e  AXX-1       True-4
4    125    at$19.d  AXX-1  SCV  True
5    785    ab&22.n  AWZ-2  DDF  False
6    849    ab&22.n  AWZ-5  DDF  False

到目前为止,我只能将一列与以下代码进行比较:

New_DF<-transform(DF_1, Status = ave(as.character(DF_1$DRC1), DF_1$DX2, FUN = function(x) 
  if(length(unique(x)) == 1) "True" else "False" ))

另外,只是想知道在MySQL中是否可以这样做。??

【问题讨论】:

  • 我相信我昨天在不同的用户名下看到了这个问题。你之前的问题怎么了?
  • @TimBiegeleisen 正确,但这不是结构化的,也没有答案...:(
  • @TimBiegeleisen 你能帮我吗??
  • 我不明白你的规则。例如,为什么 ID 1 的状态为 TRUE? DX2和DRC1不一样吗?
  • @ytu ID 1 的状态为 TRUE,因为它的 DX2 值与 ID2 的 DX2 值匹配。假设我们有一行,其所有值对于整个数据帧都是唯一的,而不是应该为真。

标签: mysql r loops if-statement matrix


【解决方案1】:

我不确定这是最好的方法还是有更优雅的解决方案,但它确实可以解决您的问题。但是,如果您有一个大型数据集,这可能会很耗时。

library(dplyr)

# Create sample data frame
df <- data.frame(
  ID = 1:6,
  SR1 = c(123,124,125,125,785,849),
  SR2 = c("as#12.c", "ae&14.v", "at$19.e", "at$19.d", "ab&22.n", "ab&22.n"),
  DRC1 = c("ABC-1", "ABC-1", "AXX-1", "AXX-1", "AWZ-2", "AWZ-5"),
  DX2 = c("SXI", "SXI", NA, "SCV", "DDF", "DDF"),
  stringsAsFactors = FALSE
)

# Create a function to give Status with each kind of DRC1 according to your rules
StatusJudge <- function(df_sub) {
  if (dim(df_sub)[1] == 1) {
    df_sub$Status <- FALSE
  }
  else {
    if (all(!is.na(df_sub$DX2))) {
      df_sub$Status <-
        ifelse(length(unique(df_sub$DX2)) == 1, TRUE, FALSE)
    }
    else {
      df_sub$Status <-
        ifelse(length(unique(df_sub$SR1)) == 1 | length(unique(df_sub$SR2)) == 1, TRUE, FALSE)
      if (any(!is.na(df_sub$DX2))) {
        df_sub$IDfound[is.na(df_sub$DX2)] <-
          df_sub$ID[!is.na(df_sub$DX2)][1]
      }
    }
  }
  return(df_sub)
}

# Apply the StatusJudge to each element of df_list and then combine the results
df <- df %>%
  mutate(Status = NA, IDfound = NA) %>%
  group_by(DRC1) %>%
  do(StatusJudge(.)) %>%
  arrange(ID)

上面的代码使df:

 ID    SR1     SR2  DRC1   DX2  Status IDfound
<int> <dbl>   <chr> <chr> <chr>  <lgl>   <int>
  1    123   as#12.c ABC-1  SXI   TRUE      NA
  2    124   ae&14.v ABC-1  SXI   TRUE      NA
  3    125   at$19.e AXX-1 <NA>   TRUE       4
  4    125   at$19.d AXX-1  SCV   TRUE      NA
  5    785   ab&22.n AWZ-2  DDF  FALSE      NA
  6    849   ab&22.n AWZ-5  DDF  FALSE      NA

我建议您在这里停下来,因为它保留了逻辑值、TRUE 和 FALSE 的性质,并且可能对您未来的分析更容易,例如检索状态为 TRUE 的行。话虽如此,您可以将 Status 和 IDfound 粘贴在一起成为新的 Status:

df$Status <-
  ifelse(!is.na(df$IDfound), paste(df$Status, df$IDfound, sep = "-"), df$Status)
df$IDfound <- NULL

,它准确地给出了您的预期输出。

【讨论】:

  • 运行时间太长...:(
  • 还在运行,已经1个多小时了。
  • 请查看我的编辑。现在应该更有效率了。
  • 我收到错误:lapply 中的错误(df_list,StatusJudge):找不到对象“df_list”
  • 我在df$Status &lt;- NA; df$IDfound &lt;- NA 之后创建了df_list。你这样做了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 2022-12-13
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多