เพิ่มคอลัมน์ให้กับองค์ประกอบภายในรายการดาต้าเฟรม

ฉันมีรายการกรอบข้อมูลที่บางกรอบมีคอลัมน์ need และบางกรอบไม่มี ฉันจะเพิ่มคอลัมน์ need ไปยังเฟรมข้อมูลอื่น (ด้วยค่า = NA) ได้อย่างไร ฉันลองใช้ Map หรือ lapply แล้ว

test <- list(data.frame(need = NA, dont_need = NA),
             data.frame(dont_need = NA),
             data.frame(dont_need = NA, dont_need_2 = NA))

เอาท์พุตที่ต้องการ

[[1]]
  need dont_need
1   NA        NA

[[2]]
  dont_need need
1        NA   NA

[[3]]
  dont_need dont_need_2 need
1        NA          NA   NA

ฉันไม่สามารถใช้การผูกได้เนื่องจากรายการนี้ถูกสร้างขึ้นแบบไดนามิกและบางครั้งก็มีเพียงหนึ่ง dataframe ที่ไม่มีคอลัมน์ need คำตอบจะต้องได้ผลในกรณีนี้:

test_2 <- list(data.frame(dont_need = NA))

person MayaGans    schedule 06.02.2020    source แหล่งที่มา


คำตอบ (4)


ความเป็นไปได้ purrr ประการหนึ่งสำหรับสถานการณ์ที่มีเพียงองค์ประกอบว่างอาจเป็น:

map(test, ~ list_modify(., need = NA))

[[1]]
  need dont_need
1   NA        NA

[[2]]
  dont_need need
1        NA   NA

[[3]]
  dont_need dont_need_2 need
1        NA          NA   NA

หากมีองค์ประกอบที่ไม่ว่างเปล่าอยู่:

map(test, ~ if(!"need" %in% names(.)) update_list(., need = NA) else .)
person tmfmnk    schedule 06.02.2020
comment
คุณควรรวม library(purrr) ไว้ในคำตอบเพื่อให้ชัดเจนยิ่งขึ้นสำหรับผู้ที่ไม่รู้ - person Gallarus; 06.02.2020
comment
ที่จริงแล้วคำตอบนี้จะลบค่าในคอลัมน์ need หากมีอยู่แล้วและไม่ใช่ NA - person Gallarus; 06.02.2020
comment
@Gallarus นั่นคือเหตุผลว่าทำไมฉันถึงรวมโซลูชันสำหรับองค์ประกอบที่มีอยู่ที่ไม่ว่างเปล่าด้วย - person tmfmnk; 06.02.2020
comment
แย่เลย ฉันตัดสินเร็วเกินไป ขอโทษด้วย - person Gallarus; 06.02.2020

อีกเวอร์ชันหนึ่งที่ใช้ lapply และ is.null ฉันเพิ่มค่าจริงบางส่วนใน data.frame เริ่มต้นเพื่อแสดงว่าค่าเหล่านั้นจะถูกเก็บไว้หากมีในตอนแรก

test <- list(data.frame(need = c(NA, 2), dont_need = 1:2),
             data.frame(dont_need = 1:3),
             data.frame(dont_need = 1:3, dont_need_2 = NA))
> [[1]]
> need dont_need
> NA         1
>  2         2
> 
> [[2]]
> dont_need
>  1
>  2
>  3
> 
> [[3]]
> dont_need dont_need_2
>  1          NA
>  2          NA
>  3          NA


test <- lapply(test, function(df) {
  if (is.null(df[["need"]])) 
    df[["need"]] <- NA

  df
})

> [[1]]
> need dont_need
>  NA         1
>   2         2
> 
> [[2]]
> dont_need need
>  1   NA
>  2   NA
>  3   NA
> 
> [[3]]
> dont_need dont_need_2 need
>  1          NA   NA
>  2          NA   NA
>  3          NA   NA
person Gallarus    schedule 06.02.2020
comment
ขอบคุณ! ด้วยความเร่งรีบในการทำซ้ำ ฉันพบว่าการไม่มีค่าใน data frame ดั้งเดิมทำให้คำตอบสับสน เนื่องจากคนด้านล่างนี้แนะนำให้แทนที่ความต้องการทั้งหมดด้วย NA - person MayaGans; 06.02.2020
comment
purrr คำตอบจาก @tmfmnk นั้นถูกต้องจริง ๆ และฉันผิด ฉันจัดเตรียมเวอร์ชันที่ไม่ลบค่าที่มีอยู่แล้ว - person Gallarus; 06.02.2020

นี่เป็นวิธีที่ตรงไปตรงมาโดยใช้ lapply:

test <- list(data.frame(need = NA, dont_need = NA),
             data.frame(dont_need = NA),
             data.frame(dont_need = NA, dont_need_2 = NA))


lapply(test, function(df) {
  if (!"need" %in% colnames(df)) {
    df$need <- NA
  }
  return(df)
})
#> [[1]]
#>   need dont_need
#> 1   NA        NA
#> 
#> [[2]]
#>   dont_need need
#> 1        NA   NA
#> 
#> [[3]]
#>   dont_need dont_need_2 need
#> 1        NA          NA   NA

สร้างเมื่อ 06-02-2020 โดยแพ็คเกจ reprex (v0.3.0)

person JBGruber    schedule 06.02.2020

คุณสามารถเขียนฟังก์ชันที่จะตรวจสอบชื่อคอลัมน์ของแต่ละ data.frame สำหรับ need แล้วสร้างขึ้นใหม่หากไม่มีอยู่

test2 <- lapply(test, function(x) {
  if(!"need"%in% colnames(x)){
    x$need <- NA
  }
  return(x)
})

[[1]]
  need dont_need
1   NA        NA

[[2]]
  dont_need need
1        NA   NA

[[3]]
  dont_need dont_need_2 need
1        NA          NA   NA
person mfidino    schedule 06.02.2020