2017-09-05 6 views
0

複数の列変数のリストが増加する場合、データフレームに新しい列を追加する必要があります。そうでない場合はR-可変incresesの複数のリスト(列)に基づいてデータフレームに動的に追加する方法

マイデータフレーム)と同じように、その列を保つ、

U_ID Value         AD CT value1    Citycode 
    1 list(`Cno`="50",'cna'="\n\rjhon\n") ia BG list(`Cno`="50")  TY 
    1 list(`Cno`="20",`cna`="guna")   AS DB list(`Cno`="\n\r20") UI 
    2 list(`Cno`="30",`cna`="rt",`cf`="ty") BN FV list(`Cno`="30")  GH 
    2 NULL         VF TY NULL     TY 
    3 list(`Cno`="\n\r30")     RR TT list(`Cno`="30")  ST 

私の欲求の出力は、

U_ID Value         Cno cna cf  AD CT value1    Cno1   Citycode 
1  list(`Cno`="50",`cna'="\n\rjhon\n") 50 jhon NULL ia BG list(`Cno1`="50")  50    TY 
1  list(`Cno`="20",`cna'="guna")   20 guna NULL  AS DB list(`Cno1`="\n\r20") 20    UI 
2  list(`Cno`="30",`cna'="rt",`cf'="ty") 30 rt ty  BN FV list(`Cno1`="30")  30    GH 
2  NULL         NULL NULL NULL VF TY NULL     NULL   TY 
3  list(`Cno`="\n\r30")     30 NULL NULL  RR TT list(`Cno1`="30")  30    ST 

データ、

になります
structure(list(U_ID = c(1, 1, 2, 2, 3), Value = list(structure(list(
    `Cno#` = "50", cna = "\n\rjhon\n"), .Names = c("Cno#", "cna" 
)), structure(list(`Cno#` = "50", cna = "guna"), .Names = c("Cno#", 
"cna")), structure(list(`Cno#` = "30", cna = "rt", cf = "ty"), .Names = c("Cno#", 
"cna", "cf")), "NULL", structure(list(`Cno#` = "\n\r30"), .Names = "Cno#")), 
    AD = c("ia", "AS", "BN", "VF", "RR"), CT = c("BG", "DB", 
    "FV", "TY", "TT"), Value1 = list(structure(list(`Cno#` = "50"), .Names = "Cno#"), 
     structure(list(`Cno#` = "\n\r20"), .Names = "Cno#"), 
     structure(list(`Cno#` = "30"), .Names = "Cno#"), "NULL", 
     structure(list(`Cno#` = "30"), .Names = "Cno#")), Citycode = c("TY", 
    "UI", "GH", "RY", "ST")), .Names = c("U_ID", "Value", "AD", 
"CT", "Value1", "Citycode"), row.names = c(NA, -5L), class = "data.frame") 
+4

あなたは何を試してみましたか? – Sotos

+0

あなたの投稿の最後のデータは、最初のデータと同じではありません。 –

+0

はい、私は値1のリスト変数に欠けています、col1は正しいです。 –

答えて

1

これはdplyrの解決法です。

library(dplyr) 

dat %>% 
    mutate(idx = as.character(`is.na<-`(cumsum(Value != "NULL"), 
             Value == "NULL"))) %>% 
    left_join(filter(., Value != "NULL") %>% 
       pull(Value) %>% 
       bind_rows(.id = "idx"), 
      by = "idx") %>% 
    mutate(idx2 = as.character(`is.na<-`(cumsum(Value1 != "NULL"), 
             Value1 == "NULL"))) %>% 
    left_join(filter(., Value1 != "NULL") %>% 
       pull(Value1) %>% 
       bind_rows(.id = "idx2"), 
      by = "idx2") %>% 
    select(-idx, -idx2) 

ここで、datは、データフレームの名前です。

結果:

U_ID   Value AD CT Value1 Citycode Cno#.x  cna cf Cno#.y 
1 1 50, \n\rjhon\n ia BG  50  TY  50 \n\rjhon\n <NA>  50 
2 1  50, guna AS DB \n\r20  UI  50  guna <NA> \n\r20 
3 2  30, rt, ty BN FV  30  GH  30   rt ty  30 
4 2   NULL VF TY NULL  RY <NA>  <NA> <NA> <NA> 
5 3   \n\r30 RR TT  30  ST \n\r30  <NA> <NA>  30 
+0

すぐにお返事ありがとうございますが、私の疑問は、動的にチェックして新しい列を追加する方法です。データフレームに50以上の列のリスト(値1、値2、値50など)がある場合は、列はリストです。私は手動で(value1、value2)を追加するのではなく、新しい列を追加する必要があります。 –

0

編集
複数のそのようなリストの列を占めているものと私の答えを置き換え。ここで


が可能な塩基Rのアプローチです:

na_if_null <- function(x) if (is.null(x)) NA else x 

new_cols <- lapply(
    Filter(is.list, df), 
    function(list_col) { 
    names_ <- setNames(nm = unique(do.call(c, lapply(list_col, names)))) 
    lapply(names_, function(name) sapply(list_col, function(x) 
     trimws(na_if_null(as.list(x)[[name]])))) 
    } 
) 

res <- do.call(
    data.frame, 
    c(
    list(df, check.names = FALSE, stringsAsFactors = FALSE), 
    do.call(c, new_cols) 
) 
) 

# U_ID   Value AD CT Value1 Citycode Value.Cno# Value.cna Value.cf Value1.Cno# 
# 1 1 50, \n\rjhon\n ia BG  50  TY   50  jhon  <NA>   50 
# 2 1  50, guna AS DB \n\r20  UI   50  guna  <NA>   20 
# 3 2  30, rt, ty BN FV  30  GH   30  rt  ty   30 
# 4 2   NULL VF TY NULL  RY  <NA>  <NA>  <NA>  <NA> 
# 5 3   \n\r30 RR TT  30  ST   30  <NA>  <NA>   30 
+0

、あなたの応答をいただきありがとうございます、上のコードのように動作fine.but私は2つの疑いがあります。 –

+0

、あなたの応答のためにありがとう、上記のデータとして、その作業fine.but私は2つの疑いがあります。 1.slowness、私は3000行と59列(列の4リスト)を実行するためには約2分かかるでしょう実行時間を短縮する方法はありますか?2。上記のコードはリスト列のために働いています私は、ネストされたリストの列と配列の列のリストで同じことをする方法。 –

0

私は、これは正確にあなたの期待される出力を与えると信じて:

library(dplyr) 
df1 %>% 
    left_join(df1 %>% 
       filter(Value != "NULL") %>% 
       mutate(Value_ = map(Value,unlist), vnames = map(Value_,names)) %>% 
       unnest(Value_,vnames) %>% 
       spread(vnames,Value_) %>% 
       rename(Cno = `Cno#`)) %>% 
    left_join(df1 %>% 
       filter(Value1 != "NULL") %>% 
       mutate(Cno1 = map(Value1,~as.numeric(unlist(.x)))) %>% 
       select(-Value,-Value1)) %>% 
    select(U_ID,Value,Cno,cna,cf,AD,CT,Value1,Cno1,Citycode) 

# U_ID   Value Cno  cna cf AD CT Value1 Cno1 Citycode 
# 1 1 50, \n\rjhon\n  50 \n\rjhon\n <NA> ia BG  50 50  TY 
# 2 1  50, guna  50  guna <NA> AS DB \n\r20 20  UI 
# 3 2  30, rt, ty  30   rt ty BN FV  30 30  GH 
# 4 2   NULL <NA>  <NA> <NA> VF TY NULL NULL  RY 
# 5 3   \n\r30 \n\r30  <NA> <NA> RR TT  30 30  ST 
関連する問題