Data.frame memungkinkan operasi pada subset kolom menggunakan [ , menjatuhkan output kolom/baris tunggal ke vektor secara default. Dplyr tidak mengizinkan ini, sengaja (dan tampaknya karena coding benar-benar mimpi buruk).

df <- data.frame(a = c(1:5,NA), b = c(1,1,1,2,2,2))
mean(df[,"a"], na.rm = T) # 3

dftbl <- as.tbl(df)
mean(dftbl[,"a"], na.rm = T) # NA

Oleh karena itu, saran untuk subset dengan [[ karena ini akan memberikan output yang seragam untuk dfs dan tbl_dfs. Tetapi: itu baik-baik saja untuk kolom atau baris saja, tetapi tidak untuk baris+kolom, dan mengenai perbedaan ini dapat dilewatkan jika Anda tidak memeriksa peringatan (yang memang kesalahan saya sendiri), mis .: .:

dfresult <- mean(df[df$b == 2, "a"], na.rm = T) # 4.5
tblresult <- mean(dftbl[dftbl$b == 2, "a"], na.rm = T) # NA_real_

Adakah yang punya saran 'praktik terbaik' untuk melakukan operasi kolom pada himpunan bagian baris? Apakah di sini saya harus meningkatkan game dplyr saya menggunakan filter & select? Upaya saya sejauh ini terus membentur tembok. Bersyukur untuk setiap aturan emas. Terima kasih sebelumnya.

dftbl %>% filter(b == 2) %>% select(a) %>% mean(na.rm = T) #NA

Ini gagal dengan cara yang sama, dengan data yang difilter & dipilih MASIH menjadi tibble N*1 yang menolak untuk bermain dengan mean.

dftbl %>% filter(b == 2) %>% select(a) %>% as.data.frame() %>% .$a
# [1]  4  5 NA

Tapi

dftbl %>% filter(b == 2) %>% select(a) %>% as.data.frame() %>% mean(.$a, na.rm = T)
# [1] NA
3
dez93_2000 20 September 2019, 22:28

1 menjawab

Jawaban Terbaik

Alasannya karena kita membutuhkan [[ bukan [ seperti [ masih tibble dengan satu kolom. mean mengharapkan input sebagai vector

mean(dftbl[["a"]], na.rm = TRUE) 
#[1] 3

Atau gunakan $

mean(dftb$a, na.rm = TRUE) 

Mengenai kasus kedua, select juga mengembalikan tibble dengan kolom yang dipilih. Sebagai gantinya, kita dapat menggunakan pull untuk mengekstrak sebagai vector

dftbl[dftbl$b == 2, "a"] %>% 
    pull(1)
#[1]  4  5 NA

Atau jika kita tidak ingin memuat pustaka apa pun, gunakan unlist

mean(unlist(dftbl[dftbl$b == 2, "a"]), na.rm = TRUE)
#[1] 4.5

Untuk kode yang disebutkan dalam posting OP

dftbl %>% 
    filter(b == 2) %>% 
    select(a)  %>%
     .$a %>%
     mean(., na.rm = TRUE)
#[1] 4.5

Atau dengan pull

dftbl %>%
    filter(b == 2) %>% 
    pull(a) %>%
    mean(na.rm = TRUE)
#[1] 4.5
2
akrun 20 September 2019, 19:50