Nhận loại của tất cả các biến


118

Trong R, tôi muốn truy xuất danh sách các biến toàn cục ở cuối tập lệnh của mình và lặp lại chúng. Đây là mã của tôi

#declare a few sample variables
a<-10
b<-"Hello world"
c<-data.frame()

#get all global variables in script and iterate over them
myGlobals<-objects()
for(i in myGlobals){
  print(typeof(i))     #prints 'character'
}

Vấn đề của tôi là typeof(i)luôn trả về charactermặc dù biến ackhông phải là biến ký tự. Làm cách nào để lấy loại biến ban đầu bên trong vòng lặp for?


Lưu ý cho những người đang đọc câu hỏi này: typeof()cung cấp một phần thông tin rất chung chung về cách đối tượng được lưu trữ trong bộ nhớ. Đối với hầu hết các trường hợp sử dụng, nếu bạn muốn biết thông tin tốt về một biến x, bạn sẽ nhận được thông tin hữu ích hơn từ class(x), is(x)hoặc str(x)(theo thứ tự bao nhiêu chi tiết mà họ cung cấp). Xem câu trả lời của Eric bên dưới để biết ví dụ về những gì typeof()cho bạn biết: các yếu tố là integer; danh sách, khung dữ liệu, các đối tượng mô hình, các đối tượng cao cấp khác chỉ là list...
Gregor Thomas

Câu trả lời:


109

Bạn cần sử dụng getđể lấy giá trị thay vì tên ký tự của đối tượng như được trả về bởi ls:

x <- 1L
typeof(ls())
[1] "character"
typeof(get(ls()))
[1] "integer"

Ngoài ra, đối với vấn đề như đã trình bày, bạn có thể muốn sử dụng eapply:

eapply(.GlobalEnv,typeof)
$x
[1] "integer"

$a
[1] "double"

$b
[1] "character"

$c
[1] "list"

Làm việc hoàn hảo. Bạn có biết liệu có bất kỳ hình phạt hiệu suất nào không nếu get () được sử dụng để tìm kiểu của một số khung dữ liệu lớn có thể có trong danh sách biến được trả về bởi đối tượng ()?

1
getcó các nhà phê bình của nó và tôi tưởng tượng eapplysẽ nhanh hơn một vòng lặp diễn giải. Nhưng chỉ có một cách để tìm ra ...
James

17

Cách lấy kiểu biến khi ẩn bên dưới đối tượng toàn cục:

Mọi thứ bạn cần đều có trong sổ tay R về các kiểu cơ bản: https://cran.r-project.org/doc/manuals/R-lang.html#Basic-types

Bạn object()cần phải được thâm nhập get(...)trước khi bạn có thể nhìn thấy bên trong. Thí dụ:

a <- 10
myGlobals <- objects()
for(i in myGlobals){
  typeof(i)         #prints character
  typeof(get(i))    #prints integer
}

Cách lấy loại biến bạn có trong R

Ví dụ, hàmtypeof R có xu hướng cung cấp cho bạn kiểu ở độ sâu tối đa.

library(tibble)

#expression              notes                                  type
#----------------------- -------------------------------------- ----------
typeof(TRUE)             #a single boolean:                     logical
typeof(1L)               #a single numeric with L postfixed:    integer
typeof("foobar")         #A single string in double quotes:     character
typeof(1)                #a single numeric:                     double
typeof(list(5,6,7))      #a list of numeric:                    list
typeof(2i)               #an imaginary number                   complex

#So far so good, but those who wish to keep their sanity go no further
typeof(5 + 5L)           #double + integer is coerced:          double
typeof(c())              #an empty vector has no type:          NULL
typeof(!5)               #a bang before a double:               logical
typeof(Inf)              #infinity has a type:                  double
typeof(c(5,6,7))         #a vector containing only doubles:     double
typeof(c(c(TRUE)))       #a vector of vector of logicals:       logical
typeof(matrix(1:10))     #a matrix of doubles has a type:       list

#Strangeness ahead, there be dragons: step carefully:
typeof(substr("abc",2,2))#a string at index 2 which is 'b' is:  character
typeof(c(5L,6L,7L))      #a vector containing only integers:    integer
typeof(c(NA,NA,NA))      #a vector containing only NA:          logical
typeof(data.frame())     #a data.frame with nothing in it:      list
typeof(data.frame(c(3))) #a data.frame with a double in it:     list
typeof(c("foobar"))      #a vector containing only strings:     character
typeof(pi)               #builtin expression for pi:            double

#OK, I'm starting to get irritated, however, I am also longsuffering:
typeof(1.66)             #a single numeric with mantissa:       double
typeof(1.66L)            #a double with L postfixed             double
typeof(c("foobar"))      #a vector containing only strings:     character
typeof(c(5L, 6L))        #a vector containing only integers:    integer
typeof(c(1.5, 2.5))      #a vector containing only doubles:     double
typeof(c(1.5, 2.5))      #a vector containing only doubles:     double
typeof(c(TRUE, FALSE))   #a vector containing only logicals:    logical

#R is really cramping my style, killing my high, irritation is increasing:
typeof(factor())         #an empty factor has default type:     integer
typeof(factor(3.14))     #a factor containing doubles:          integer
typeof(factor(T, F))     #a factor containing logicals:         integer
typeof(Sys.Date())       #builtin R dates:                      double
typeof(hms::hms(3600))   #hour minute second timestamp          double
typeof(c(T, F))          #T and F are builtins:                 logical
typeof(1:10)             #a builtin sequence of numerics:       integer
typeof(NA)               #The builtin value not available:      logical

#The R coolaid punchbowl has been spiked: stay frosty and keep your head low:
typeof(c(list(T)))       #a vector of lists of logical:         list
typeof(list(c(T)))       #a list of vectors of logical:         list
typeof(c(T, 3.14))       #a vector of logicals and doubles:     double
typeof(c(3.14, "foo"))   #a vector of doubles and characters:   character
typeof(c("foo",list(T))) #a vector of strings and lists:        list
typeof(list("foo",c(T))) #a list of strings and vectors:        list
typeof(TRUE + 5L)        #a logical plus an integer:            integer
typeof(c(TRUE, 5L)[1])   #The true is coerced to 1              integer
typeof(c(c(2i), TRUE)[1])#logical coerced to complex:           complex
typeof(c(NaN, 'batman')) #NaN's in a vector don't dominate:     character
typeof(5 && 4)           #doubles are coerced by order of &&    logical
typeof(8 < 'foobar')     #string and double is coerced          logical
typeof(list(4, T)[[1]])  #a list retains type at every index:   double
typeof(list(4, T)[[2]])  #a list retains type at every index:   logical
typeof(2 ** 5)           #result of exponentiation              double
typeof(0E0)              #exponential lol notation              double
typeof(0x3fade)          #hexidecimal                           double
typeof(paste(3, '3'))    #paste promotes types to string        character
typeof(3 +)           #R pukes on unicode                    error
typeof(iconv("a", "latin1", "UTF-8")) #UTF-8 characters         character
typeof(5 == 5)           #result of a comparison:               logical

Cách lấy lớp của một biến bạn có trong R

Ví dụ, hàmclass R có xu hướng cung cấp cho bạn kiểu vùng chứa hoặc cấu trúc đóng gói các kiểu của bạn.

library(tibble)

#expression            notes                                    class
#--------------------- ---------------------------------------- ---------
class(matrix(1:10))     #a matrix of doubles has a class:       matrix
class(factor("hi"))     #factor of items is:                    factor
class(TRUE)             #a single boolean:                      logical
class(1L)               #a single numeric with L postfixed:     integer
class("foobar")         #A single string in double quotes:      character
class(1)                #a single numeric:                      numeric
class(list(5,6,7))      #a list of numeric:                     list
class(2i)               #an imaginary                           complex
class(data.frame())     #a data.frame with nothing in it:       data.frame
class(Sys.Date())       #builtin R dates:                       Date
class(sapply)           #a function is                          function
class(charToRaw("hi"))  #convert string to raw:                 raw
class(array("hi"))      #array of items is:                     array

#So far so good, but those who wish to keep their sanity go no further
class(5 + 5L)           #double + integer is coerced:          numeric
class(c())              #an empty vector has no class:         NULL
class(!5)               #a bang before a double:               logical
class(Inf)              #infinity has a class:                 numeric
class(c(5,6,7))         #a vector containing only doubles:     numeric
class(c(c(TRUE)))       #a vector of vector of logicals:       logical

#Strangeness ahead, there be dragons: step carefully:
class(substr("abc",2,2))#a string at index 2 which is 'b' is:  character
class(c(5L,6L,7L))      #a vector containing only integers:    integer
class(c(NA,NA,NA))      #a vector containing only NA:          logical
class(data.frame(c(3))) #a data.frame with a double in it:     data.frame
class(c("foobar"))      #a vector containing only strings:     character
class(pi)               #builtin expression for pi:            numeric

#OK, I'm starting to get irritated, however, I am also longsuffering:
class(1.66)             #a single numeric with mantissa:       numeric
class(1.66L)            #a double with L postfixed             numeric
class(c("foobar"))      #a vector containing only strings:     character
class(c(5L, 6L))        #a vector containing only integers:    integer
class(c(1.5, 2.5))      #a vector containing only doubles:     numeric
class(c(TRUE, FALSE))   #a vector containing only logicals:    logical

#R is really cramping my style, killing my high, irritation is increasing:
class(factor())       #an empty factor has default class:      factor
class(factor(3.14))   #a factor containing doubles:            factor
class(factor(T, F))   #a factor containing logicals:           factor
class(hms::hms(3600)) #hour minute second timestamp            hms difftime
class(c(T, F))        #T and F are builtins:                   logical
class(1:10)           #a builtin sequence of numerics:         integer
class(NA)             #The builtin value not available:        logical

#The R coolaid punchbowl has been spiked: stay frosty and keep your head low:
class(c(list(T)))       #a vector of lists of logical:         list
class(list(c(T)))       #a list of vectors of logical:         list
class(c(T, 3.14))       #a vector of logicals and doubles:     numeric
class(c(3.14, "foo"))   #a vector of doubles and characters:   character
class(c("foo",list(T))) #a vector of strings and lists:        list
class(list("foo",c(T))) #a list of strings and vectors:        list
class(TRUE + 5L)        #a logical plus an integer:            integer
class(c(TRUE, 5L)[1])   #The true is coerced to 1              integer
class(c(c(2i), TRUE)[1])#logical coerced to complex:           complex
class(c(NaN, 'batman')) #NaN's in a vector don't dominate:     character
class(5 && 4)           #doubles are coerced by order of &&    logical
class(8 < 'foobar')     #string and double is coerced          logical
class(list(4, T)[[1]])  #a list retains class at every index:  numeric
class(list(4, T)[[2]])  #a list retains class at every index:  logical
class(2 ** 5)           #result of exponentiation              numeric
class(0E0)              #exponential lol notation              numeric
class(0x3fade)          #hexidecimal                           numeric
class(paste(3, '3'))     #paste promotes class to string       character
class(3 +)           #R pukes on unicode                   error
class(iconv("a", "latin1", "UTF-8")) #UTF-8 characters         character
class(5 == 5)           #result of a comparison:               logical

Nhận dữ liệu storage.modecủa biến của bạn

Khi một biến R được ghi vào đĩa, bố cục dữ liệu lại thay đổi và được gọi là dữ liệustorage.mode . Chức năng storage.mode(...)tiết lộ thông tin ở mức độ thấp này: xem Mode, Class, và Type của các đối tượng nghiên cứu . Bạn không cần phải lo lắng về chế độ lưu trữ của R trừ khi bạn đang cố gắng tìm hiểu sự chậm trễ do phôi / cưỡng chế khứ hồi xảy ra khi gán và đọc dữ liệu vào và từ đĩa.

Ý tưởng xung quanh hệ thống gõ bộ ba của R:

Hệ thống gõ vịt của R có sự không chắc chắn trong đó. Một phép tương tự, hãy xem xét một chiếc cốc sứ, nó có thể được sử dụng để đựng chất lỏng, hoặc được sử dụng như một vật phóng như quả bóng chày. Mục đích của cốc phụ thuộc vào các đặc tính sẵn có của nó và chức năng hoạt động của nó. Tính linh hoạt của kiểu này cho phép các lập trình viên có nhiều thời gian hơn để chuyển hướng bất kỳ loại đầu ra nào từ một chức năng này sang một chức năng khác, và R sẽ rất lâu để cố gắng đọc suy nghĩ của bạn và làm điều gì đó hợp lý.

Ý tưởng là khi các lập trình viên mới viết chương trình R thông qua chuyển động Brownian, như họ sẽ làm, họ sẽ cố gắng chuyển a googah.blimflargthành a vehicle.subspaceresponder(...). Thay vì phát ra lỗi kiểu, chương trình R thực hiện thể dục dụng cụ để biến đổi kiểu và sau đó làm điều gì đó hữu ích đáng ngạc nhiên. Lập trình viên mới này đăng đoạn mã trên blog của mình và nói "hãy nhìn điều to lớn này mà tôi đã làm với 3 dòng mã R! Tôi không biết nó biết phải làm gì, nhưng nó đã làm được!"


làm thế nào để xác định ví dụ ds <- c (3,4,5,5,3) - rằng "ds" là chính xác vectơ với kiểu số chứa?
Max Usanin

1
Tạo hàm R tùy chỉnh của riêng bạn mà bạn giữ trong hộp công cụ của mình có tham số x. Bên trong hàm sử dụng các câu lệnh if để kiểm tra xem typeof (x) có phải là số hay không và nếu class (x) là vector. Nếu vậy, hãy in ra chuỗi: "x chính xác là một vectơ có kiểu số". R sẽ không giúp bạn trong phần này vì hệ thống gõ bộ ba này có độ phức tạp vô hạn, phân tích kiểu là không thể, ngay khi bạn xác định tất cả các kiểu, ai đó sẽ xác định một kiểu mới. Hệ thống gõ R là thứ tồi tệ nhất mà tôi từng thấy trong bất kỳ ngôn ngữ nào. Đó là một đám cháy bãi rác.
Eric Leschinski

6

Bạn có thể sử dụng class (x) để kiểm tra kiểu biến. Nếu yêu cầu là kiểm tra tất cả kiểu biến của khung dữ liệu thì có thể sử dụng sapply (x, class).


4
> mtcars %>% 
+     summarise_all(typeof) %>% 
+     gather
    key  value
1   mpg double
2   cyl double
3  disp double
4    hp double
5  drat double
6    wt double
7  qsec double
8    vs double
9    am double
10 gear double
11 carb double

Tôi thử classvà các typeofchức năng, nhưng tất cả đều không thành công.


1

Được thiết kế để làm ngược lại những gì bạn muốn, đây là một trong những đồ chơi trong bộ công cụ của tôi:

 lstype<-function(type='closure'){
inlist<-ls(.GlobalEnv)
if (type=='function') type <-'closure'
typelist<-sapply(sapply(inlist,get),typeof)
return(names(typelist[typelist==type]))
}

0

lapply (your_dataframe, class) cung cấp cho bạn một cái gì đó như:

$ tikr [1] "hệ số"

$ Date [1] "Ngày"

$ Mở [1] "số"

$ High [1] "số"

... Vân vân.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.