Cara mudah untuk menambahkan observasi ke kerangka data yang ada?

Saya memiliki kerangka data yang ingin saya tambahkan pengamatan terbaru. Saya dapat mengidentifikasi observasi terbaru ini dengan ID dan variabel titik waktu. Saya telah mencoba menghapus pengamatan usang dari kerangka data yang ada dan kemudian mencoba menggunakan fungsi merge() untuk menggabungkan dengan kerangka data hanya dengan pengamatan yang diperbarui, tetapi saya mendapatkan kolom duplikat. Apakah ada cara yang elegan untuk melakukan ini (terutama menggunakan dplyr?)

Berikut ini contoh yang ingin saya lakukan: Katakanlah saya mempunyai df, yang disebut latihan

practice

ID     Time  score 1 score 2 
 1   hour 1        3       7
 1   hour 2        4       2
 2   hour 1        3       4

Katakanlah saya ingin mengubah variabel skor 1 untuk observasi ketiga (yang ID==2 dan Waktu==='jam 1'), dari 3 menjadi 5.

Yang saya coba adalah membuat kerangka data baru, yang disebut latihan1:

ID     Time  score 1  score 2 
 1   hour 1        3        7
 1   hour 2        4        2

Yang menghapus observasi ketiga, dan kemudian membuat kerangka data baru lainnya dengan observasi yang dikoreksi, yang disebut latihan2:

   ID     Time  score 1  score 2 
    2   hour 1        3        4

Saya kemudian mencoba melakukan sesuatu seperti ini:

Practice3 <- merge(practice2, practice1, by = "ID", all = T)

Namun, saya akan mendapatkan kolom duplikat, dan ketika saya mencoba memasukkan beberapa variabel dalam pernyataan by= di fungsi penggabungan, saya mendapatkan kesalahan ini:

Error in fix.by(by.x, x) : 'by' must specify a uniquely valid column

Manakah yang mungkin disebabkan oleh sifat data yang memanjang?

Terima kasih


person baldirony    schedule 19.04.2017    source sumber
comment
Berikan beberapa contoh data stackoverflow.com/questions/5963269/   -  person neilfws    schedule 20.04.2017
comment
Maaf, saya mencoba menambahkan beberapa contoh data dalam editan saya.   -  person baldirony    schedule 20.04.2017
comment
@ G5W Ya memang; Saya mengedit postingan tersebut sesuai dengan itu. Terima kasih.   -  person baldirony    schedule 20.04.2017


Jawaban (3)


Anda dapat melakukan substitusi tempat pada variabel dalam bingkai data. Misalnya.:

practice[["Score 1"]][practice$ID == 2 & practice$Time=="hour 1"] <- 5
person thc    schedule 20.04.2017
comment
Atau practice[practice$ID == 2 & practice$Time == "hour 1", "score 1"] <- 5 untuk menyederhanakannya sedikit - person thelatemail; 20.04.2017
comment
Selain itu, Anda perlu mereferensikan practice$Time, bukan hanya Time. - person thelatemail; 20.04.2017
comment
Terima kasih, mungkin ini yang saya butuhkan. Saya pikir tanda kurung ganda hanya digunakan saat menangani daftar. - person baldirony; 20.04.2017
comment
@baldirony - data.frames adalah daftar. - person thelatemail; 20.04.2017
comment
@thelatemail Oh, jadi apakah dfs hanya daftar objek = 1? - person baldirony; 20.04.2017
comment
@baldirony - data.frames adalah daftar yang setiap kolomnya merupakan item daftar dengan panjang yang sama. Bandingkan as.list(mtcars) dengan mtcars - person thelatemail; 20.04.2017
comment
Ya, data.frames adalah kelas turunan dari daftar, dan mewarisi semua metode daftar: programiz.com /r-pemrograman/warisan - person thc; 20.04.2017

Berikut pembaruan menggunakan dplyr::mutate. Catatan: Saya mengganti nama kolom untuk menghilangkan spasi.

library(dplyr)
practice %>% 
  mutate(score1 = ifelse(ID == 2 & Time == "hour 1", 5, score1))
person neilfws    schedule 20.04.2017

Jika Anda sudah memiliki data baru di data.frame, Anda dapat menggunakan anti_join untuk menghapus kasus lama dan kemudian gunakan bind_rows untuk menambahkan kasus baru:

library(dplyr)

practice <- read.table(text = 'ID     Time  score1 score2 
                                1    hour1       3      7
                                1    hour2       4      2
                                2    hour1       3      4', 
                       header = TRUE, stringsAsFactors = FALSE)

practice2 <- read.table(text = 'ID     Time  score1  score2 
                                 2    hour1       5       5', 
                        header = TRUE, stringsAsFactors = FALSE)

practice %>% 
    anti_join(practice2, by = c('ID', 'Time')) %>% 
    bind_rows(practice2)

#>   ID  Time score1 score2
#> 1  1 hour2      4      2
#> 2  1 hour1      3      7
#> 3  2 hour1      5      5

Namun, hal ini tidak akan berfungsi dengan baik jika practice2 tidak memiliki kolom, dalam hal ini Anda dapat menggunakan coalesce untuk menimpa nilai lama dengan nilai baru:

left_join(practice, practice2, by = c('ID', 'Time')) %>% 
    mutate(score1 = coalesce(score1.y, score1.x), 
           score2 = coalesce(score2.y, score2.x)) %>% 
    select(-contains('.'))

#>   ID  Time score1 score2
#> 1  1 hour1      3      7
#> 2  1 hour2      4      2
#> 3  2 hour1      5      5
person alistaire    schedule 20.04.2017