[,]和$之间的逻辑陈述的差异

时间:2017-03-17 14:47:11

标签: r vector dataframe logic

我正在制作一个数据框(' df_temp'),其中有两列客户ID(' Custid')和收入('收入'):

  Custid    Income
  <fctr>     <dbl>
1   1003  29761.20
2   1004  98249.55
3   1006  23505.30
4   1007  72959.25
5   1009 114973.95
6   1010  25038.30

在检查收入是否为数字时,我遇到以下问题:

使用$来引用收入,返回TRUE:

> is.numeric(df_temp$Income)
[1] TRUE

使用[,2]或[,(...())来引用收入,返回FALSE:

> i <- which(names(df_temp)=='Income')
> is.numeric(df_temp[,i])
[1] FALSE
> is.numeric(df_temp[,2])
[1] FALSE

当尝试使用[,]将此向量设置为数字时,我遇到了另一个问题:

> df_temp[,2] <- as.numeric(df_temp[,2])
Error: (list) object cannot be coerced to type 'double'

我一直认为$和[]在引用数据框中的向量时起到同样的作用。

有人可以帮助我理解问题并使用[,]表达式将此向量转换为数字吗?

3 个答案:

答案 0 :(得分:10)

您没有使用data.frame。你正在使用“tbl_df”。使用$子集tbl_df会返回一个向量。使用[子集tbl_df会返回tbl_df,而tbl_df不是数字向量,因此is.numeric会返回FALSE

tbl_df执行的一件事是在调用drop = FALSE时使用[。但是,通过积极阻止你设置drop = TRUE

,它会更进一步
x <- tbl_df(mtcars)
is.numeric(x[,"cyl",drop=TRUE])
# [1] FALSE
Warning messages:
1: drop ignored 

因此,您不能以您想要的方式使用[和tbl_df。您必须使用$[[来提取矢量。

is.numeric(x$cyl)
# [1] TRUE
is.numeric(x[["cyl"]])
# [1] TRUE

答案 1 :(得分:3)

要完全回答这个问题,$和[在标准data.frame对象上实现相同的目的:

Custid <- c(1003, 1004, 1006, 1007, 1009, 1010)
Income <- c(29761.20, 98249.55, 23505.30, 72959.25, 114973.95, 25038.30)
mydf <- data.frame(Custid, Income)
class(mydf$Income); class(mydf[ , 2])

您正在处理tbl_df对象:

library(dplyr)
mytbl_df <- tbl_df(mydf)
print(mytbl_df)
## A tibble: 6 × 2
#  Custid    Income
#   <dbl>     <dbl>
#1   1003  29761.20
#2   1004  98249.55
#3   1006  23505.30
#4   1007  72959.25
#5   1009 114973.95
#6   1010  25038.30

要[在mytbl_df上照常工作,只需将其转换回data.frame:newdf <- as.data.frame(mytbl_df)

答案 2 :(得分:1)

我们有tbl_df个对象,因此使用[进行提取仍然是tbl_df,即

df_temp[,i]
# A tibble: 6 × 1
#     Income
#      <dbl>
#1  29761.20
#2  98249.55
#3  23505.30
#4  72959.25
#5 114973.95
#6  25038.30

我们可以进行[[提取

df_temp[[i]]
#[1]  29761.20  98249.55  23505.30  72959.25 114973.95  25038.30


is.numeric(df_temp[[i]])
#[1] TRUE

数据

df_temp <- structure(list(Custid = c(1003L, 1004L, 1006L, 1007L, 1009L, 
1010L), Income = c(29761.2, 98249.55, 23505.3, 72959.25, 114973.95, 
25038.3)), .Names = c("Custid", "Income"), row.names = c("1", 
"2", "3", "4", "5", "6"), class = c("tbl_df", "tbl", "data.frame"))