【问题标题】:Turn field names into column names for specific variables and fill them with certain logic将字段名转换为特定变量的列名,并用一定的逻辑填充它们
【发布时间】:2018-09-12 02:26:42
【问题描述】:

我有下面的数据框:

product<-c("ab","ab","ab","ac","ac","ac")
shop<-c("sad","sad","sad","sadas","fghj","xzzv")
category<-c("a","a","a","c","b","b")
tempr<-c(35,35,14,24,14,5)
value<-c(0,0,-6,8,4,0)
store<-data.frame(product,shop,category,tempr,value)


product  shop category tempr value
1      ab   sad        a    35     0
2      ab   sad        a    35     0
3      ab   sad        a    14    -6
4      ac sadas        c    24     8
5      ac  fghj        b    14     4
6      ac  xzzv        b     5     0

我想以一种保留唯一产品名称并将商店名称从字段值转换为列名称(反之亦然)的方式转换此数据框。我想用tempr 及其相对value 的组合填充此数据框,但仅适用于非 0 的值,否则单元格应为空。但是,正如您注意到的,我的记录具有相同的 productshop,但不同的 tempr 和 value 数字 (ab-sad)。问题是它们相互覆盖。在这种情况下(相同名称,相同商店但不同tmpr-value)应以非零情况为准。例如,如果它们都存在,则应显示 170(62) 而不是 170(0)。如果商店中不存在产品,则单元格也应为空。最终形式的一个例子是:

store2
  product    sad sadas  fghj xzzv
1      ab 14(-6)                 
2      ac        24(8) 14(4)  

第一种可能的方法:

store2 <- matrix(NA,ncol=length(unique(store$shop)),nrow=length(unique(store$product)))
colnames(store2) <- unique(store$shop)
rownames(store2) <- unique(store$product)

for(i in 1:ncol(store)) {
  store2[store[i,'product'],store[i,'shop']] <- paste0(store[i,c('tempr')],'(',store[i,'value'],')')
}

第二种可能的方法:

library(tidyverse)
store %>%
    mutate(shop = factor(shop, levels = unique(shop))) %>%
    filter(value != 0) %>%
    mutate(val = sprintf("%s(%s)", tempr, value)) %>%
    select(product, shop, val) %>%
    group_by(product) %>%
    complete(shop) %>%
    spread(shop, val)

除了这个结果之外,我希望能够以相同的逻辑使用category。下图显示了我希望使用相同填充逻辑的所有可能组合。

【问题讨论】:

    标签: r


    【解决方案1】:

    不确定我是否完全理解这个问题,但下面的代码会生成您的示例数据框。

    library(tidyverse)
    product<-c("ab","ab","ab","ac","ac","ac")
    shop<-c("sad","sad","sad","sadas","fghj","xzzv")
    category<-c("a","a","a","c","b","b")
    tempr<-c(35,35,14,24,14,5)
    value<-c(0,0,-6,8,4,0)
    store<-data.frame(product,shop,category,tempr,value)
    
    
    store %>% filter(value != 0 ) %>%  # Remove 0 values 
      mutate(combined =  paste0(tempr,"(",value,")")) %>% # Combine columns for spread
      select(-tempr,-value) %>%  #
      spread(shop,combined) # spread to create shop columns and temr/value values. 
    
      #       product category  fghj    sad     sadas
      # 1      ab        a      <NA>    14(-6)  <NA>
      # 2      ac        b       14(4) <NA>     <NA>
      # 3      ac        c      <NA>   <NA>     24(8)
    

    【讨论】:

    • 很好 - 可能只是缺少空列 xzzv?
    【解决方案2】:
    store$shop<-factor(store$shop,levels=c("sad","sadas","fghj","xzzv")) 
     #to avoid the change of column sequence of final outcome
    
    store$tv<-ifelse(store$value==0,"",paste(store$tempr,"(",store$value,")",sep=""))
    
    cast(store[,c(-3,-4,-5)],product~shop,function(x) paste(x,sep="",collapse=""), value="tv")
    #due to one colname of the original store dataset is "value", firstly masked 
    #the original "value" column,otherwise, it automatically used as value-fill 
    # column
    
    产品 sadas fghj xzzv
         ab 14(-6)
         ac 24(8) 14(4)"
    

    【讨论】:

      猜你喜欢
      • 2021-07-20
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2020-06-18
      • 1970-01-01
      相关资源
      最近更新 更多