【问题标题】:Loop through dataframe to get a string循环遍历数据框以获取字符串
【发布时间】:2021-09-10 18:43:35
【问题描述】:

我喜欢这样的数据框:

  v w  e  
1 d f  -- 
2 d a  -> 
3 f a  -> 
4 q a  -> 

并写了这个函数:

convert_dag <- function(df,v,w,e) {
  z <- 'dag{'
  for (row in 1:nrow(df)) {
    if (df[row,'v'] == v && df[row,'w'] == w) {
      z <- paste(z,paste(df[row,'v'], e, df[row,'w']), collapse = '')
    } else {
      z <- paste(z,paste(df[row,'v'], df[row,'e'], df[row,'w']), collapse = '')
    }
  }
  z <- paste(z,'}')
  z
}

此函数将获取数据帧并根据用户输入更新值并输出字符串。我的问题是,是否有更有效的方式使用 tidyverse 语法编写此代码?

例子:

> convert_dag(df,'d','f','->')
[1] "dag{ d -> f d -> a f -> a q -> a }"

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    当然可以。

    library(tidyverse)
    df = tribble(
      ~v,  ~w,  ~e,  
      "d", "f",  "--", 
      "d", "a",  "->", 
      "f", "a",  "->", 
      "q", "a",  "->")
    
    convert_dag = function(df,V,W,E) {
      df %>% mutate(
        txt = ifelse(v==V & w==W, paste(V,E,W), paste(v,e,w))
      ) %>% pull(txt) %>% paste(.,collapse = " ") %>%  paste('dag{',.,'}')
    }
    convert_dag(df, "d", "f", "->")
    #[1] "dag{ d -> f d -> a f -> a q -> a }"
    

    更新 1

    n = 40
    tibble(
      id = 1:n,
      V = sample(c("d", "f", "q"), n, replace = TRUE),
      W = sample(c("a", "f"), n, replace = TRUE),
      e = sample(c("--", "->", "<-", "->>", "<<-"), n, replace = TRUE)
    ) %>% group_by(id) %>% 
      nest(data=V:e) %>% 
      mutate(con_dag = map(data, ~convert_dag(df, .x$V, .x$W, .x$e))) %>% 
      unnest(data:con_dag)
    

    输出

    # A tibble: 40 x 5
    # Groups:   id [40]
          id V     W     e     con_dag                            
       <int> <chr> <chr> <chr> <chr>                              
     1     1 q     f     ->>   dag{ d -- f d -> a f -> a q -> a } 
     2     2 f     a     ->    dag{ d -- f d -> a f -> a q -> a } 
     3     3 f     f     --    dag{ d -- f d -> a f -> a q -> a } 
     4     4 f     a     ->    dag{ d -- f d -> a f -> a q -> a } 
     5     5 q     a     ->>   dag{ d -- f d -> a f -> a q ->> a }
     6     6 q     a     <<-   dag{ d -- f d -> a f -> a q <<- a }
     7     7 q     f     <<-   dag{ d -- f d -> a f -> a q -> a } 
     8     8 f     f     <-    dag{ d -- f d -> a f -> a q -> a } 
     9     9 d     a     ->    dag{ d -- f d -> a f -> a q -> a } 
    10    10 q     a     ->    dag{ d -- f d -> a f -> a q -> a } 
    # ... with 30 more rows
    

    注意,由于tibble 突变的特定构造,它必须包含一个分组变量。这里是变量id

    更新 2

    tibble(
      id = 1:2,
      V = c('d','d'),
      W = c('f','a'),
      e = c('->','<-')
    ) %>% group_by(id) %>%
      nest(data=V:e) %>%
      mutate(con_dag = map(data, ~convert_dag(df, .x$V, .x$W, .x$e))) %>%
      unnest(data:con_dag)
    

    输出

    # A tibble: 2 x 5
    # Groups:   id [2]
         id V     W     e     con_dag                           
      <int> <chr> <chr> <chr> <chr>                             
    1     1 d     f     ->    dag{ d -> f d -> a f -> a q -> a }
    2     2 d     a     <-    dag{ d -- f d <- a f -> a q -> a }
    

    现在清楚了吗?

    更新 3

    convert_dag2 = function(df,V,W,E) {
      df %>% mutate(
        test = v %in% V & w %in% W,
        txt = ifelse(test, paste(V,E,W), paste(v,e,w))
      ) %>% pull(txt) %>% paste(.,collapse = " ") %>%  paste('dag{',.,'}')
    }
    convert_dag2(df, c('d','d'), c('f','a'), c('->','<-'))
    # [1] "dag{ d -> f d <- a f -> a q -> a }"
    

    【讨论】:

    • 这真的很棒。如果输入现在是列表,您知道如何调整此代码吗?例如..以下会给我以下结果。 convert_dag(df, c('d','d'), c('f','a'), c('-&gt;','&lt;-')) #[1]"dag{ d -&gt; f d &lt;- a f -&gt; a q -&gt; a }"
    • 嗯,在lists 上?为什么不在tibble 上?函数convert_dag 无需更改任何内容。您只需要适当地操作 'tibble。查看我的更新。
    • 我不明白你的解决方案。输出应该仍然是一个字符串。但是输入 V、W、E 现在是列表,其中每个列表的第 0 个元素是变化的,第一个元素是变化的,依此类推。
    • 看看我的tibble。变量V = c ('d', 'd')、变量W = c ('f', 'a') 和变量e = c ('-&gt;', '&lt;-')。这不是你所期望的吗?变量VWe 的这些值必须产生两个相等的字符串,您可以在变量con_dag 中找到它们
    • 对不起,我有点困惑。似乎con_dag 是每次更改的字符串。然而,它应该完全是一个变化。 IE。应该输出字符串“dag{ d -> f d a q -> a }”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    • 2023-03-23
    • 2019-08-18
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多