【问题标题】:Looping in a data frame in R until a certain condition is met在R中循环数据帧直到满足某个条件
【发布时间】:2021-08-26 11:00:50
【问题描述】:

我们有如下的当前数据框df

df <- data.frame(ID = c(1,2,3,4,5,6), Name = c("Chris", "J", "Kemp", "President,", "CEO & ", "Director", "Ashton", "K", "Christian", "Analyst"), 
                  Font = c("Font A", "Font A", "Font A", "Font B", "Font B", "Font B", "Font A", "Font A", "Font A", "Font B"))

预期的输出是

final_df <- data.frame(Name =  c("Chris J Kemp", "Ashton K Christian"), Designation = c("President, CEO & Director", "Analyst"))

所以基本上我想添加名称,直到在 Font 列中有某种字体类型,这当然是我正在处理的巨大数据框的一个示例。提前感谢您的帮助!

对不起你之前的所有努力。这个问题已经重新编辑了一点。

【问题讨论】:

  • "Font A""Font B" 是否为另一个人再次重复?您能否提供一个至少有 2 人的示例,以便更容易提供一般性答案。
  • 是的,我在 df$Name 列下有更多名称,但顺序保持不变,名称属于字体 A,名称属于字体 B

标签: r dataframe loops


【解决方案1】:

数据:

df <- data.frame(
  ID = c(1:12), 
  Name = c("Chris", "J", "Kemp", "President,", "CEO & ", "Director", 
           "Bad", "D", "King", "Best,", "Teacher & ", "Friend"), 
  Font = c("Font A", "Font A", "Font A", "Font B", "Font B", "Font B",
           "Font A", "Font A", "Font A", "Font B", "Font B", "Font B")
)

你可以这样做:

df$group <- cumsum(c(TRUE, df$Font[-1] != df$Font[-length(df$Font)]))
final_df <- as.data.frame(matrix(lapply(split(df$Name, df$group), paste, collapse = " "), ncol = 2))
colnames(final_df) <- c("Name", "Designation")

创建了连续字体的分组行。然后split 允许每个字体有一个列表,然后您可以使用paste 重新格式化数据。

输出:

                        Name             Designation
1               Chris J Kemp              Bad D King
2 President, CEO &  Director Best, Teacher &  Friend

【讨论】:

  • 嘿,谢谢您的回答。但是我在 df$Name 列下有更多名称,序列保持相同,名称属于字体 A,名称属于字体 B 到目前为止,我面临的问题是我正在获取所有名称和名称堆叠在一行下。
  • 能否更新您的示例,以便我们更好地理解您的问题并调整我们的答案?
  • @AishwaryaSharma 请看看我的更新答案
【解决方案2】:

你可以试试-

library(dplyr)
library(tidyr)

df %>%
  mutate(Font = recode(Font, 'Font A' = 'Name', 'Font B' = 'Designation'), 
         ID = data.table::rleid(Font)) %>%
  group_by(ID, Font) %>%
  summarise(Name = toString(Name), .groups = 'drop') %>%
  mutate(ID = ceiling(ID/2)) %>%
  pivot_wider(names_from = Font, values_from = Name) %>%
  select(-ID)

#  Name                 Designation                 
#  <chr>                <chr>                       
#1 Chris, J, Kemp       President,, CEO & , Director
#2 Ashton, K, Christian Analyst                     

【讨论】:

    【解决方案3】:

    这个方法怎么样:

    df_final = as.data.frame(matrix(unlist(lapply(unique(df$Font),function(i){paste(collapse = ' ', df[df$Font%in%i,"Name"])})), byrow=T,ncol = 2))
    
    colnames(df_final)=c("names", "designation")
    

    让我知道是否可以

    【讨论】:

    • 您好,谢谢您的回答。但是我在 df$Name 列下有更多名称,序列保持相同,名称属于字体 A,名称属于字体 B 到目前为止,我面临的问题是我正在获取所有名称和名称堆叠在单行下。
    【解决方案4】:

    这是dplyr的解决方案:

    library(dplyr)
    
    df %>%
      group_by(Font, fontnum) %>%
      summarize(Tmp = paste(Name, collapse = " ")) %>% 
      mutate(ID = fontnum %/% 2) %>% 
      pivot_wider(id_cols = ID, names_from = Font, values_from = Tmp) %>%
      transmute(Name = `Font A`, Designation = `Font B`)
    

    在哪里

    df <- data.frame(
      ID = 1:12, 
      Name = c("Chris", "J", "Kemp", "President,", "CEO & ", "Director", 
               "Bad", "D", "King", "Best,", "Teacher & ", "Friend"), 
      Font = c("Font A", "Font A", "Font A", "Font B", "Font B", "Font B",
               "Font A", "Font A", "Font A", "Font B", "Font B", "Font B")
    )
    

    df$fontnum <- cumsum(c(0, abs(diff(as.numeric(factor(df$Font))))))
    

    结果会是

    # A tibble: 2 × 2
      Name         Designation               
      <chr>        <chr>                     
    1 Chris J Kemp President, CEO &  Director
    2 Bad D King   Best, Teacher &  Friend  
    

    【讨论】:

    • 您好,谢谢您的回答。但是我在 df$Name 列下有更多名称,序列保持相同,名称属于字体 A,名称属于字体 B 到目前为止,我面临的问题是我正在获取所有名称和名称堆叠在单行下。 ——
    • 从这个答案我了解到,在调用需要反引号的函数时,可以使用引号代替反引号 - 考虑到我的键盘上没有反引号(必须使用快捷方式),这将很有用,但同时我可能更喜欢反引号,以避免与字符串的引号混淆。无论如何谢谢
    • 如果你使用group_by(Font, ID = cumsum(c(0, abs(diff(as.numeric(factor(Font)))))) %/% 2),你既不需要mutate也不需要fontnum的定义(在管道外)。
    【解决方案5】:

    这是dplyr 的替代策略:使用来自 Clemsang 的数据(非常感谢!)

    1. group_by 并将 ID 除以 3
    2. summarisecollapse(将行按组归为一行)
    3. 使用group_split 拆分组(返回列表)
    4. 使用bind_cols 获取数据帧
    5. 调整名称并选择
    library(dplyr)
    df %>% 
        group_by(Font, ceiling(ID/3)) %>%
        summarise(Name = paste0(Name, collapse = " ")) %>% 
        group_split(Font) %>%
        bind_cols() %>% 
        select(Name = Name...3, Designation=Name...6)
    
      Name         Designation               
      <chr>        <chr>                     
    1 Chris J Kemp President, CEO &  Director
    2 Bad D King   Best, Teacher &  Friend   
    

    【讨论】:

      猜你喜欢
      • 2014-05-12
      • 2016-05-02
      • 2021-12-24
      • 1970-01-01
      • 2018-11-09
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 2018-12-24
      相关资源
      最近更新 更多