我是一个开始使用R的用户,我有一个关于我遇到的问题的疑问:
- 非常大的数据集(几乎800k行)
- 此数据集列出了90年代美国政治家的所有捐款
在一些数据清理之后,我需要将列表减少到更易于管理的大小。因为我对不止一次捐赠的贡献者感兴趣,所以我决定尝试限制数据集的大小。
数据集被加载为"cont"
我的意图:
-
地图提及频率:
> table(cont$contributor_name) -> FreqCon > subset(FreqCon,Freq>4) -> FMI
-
插入一个额外的列作为名称为"include"的cont[,43],该列将为TRUE或FALSE表示是否应该将其作为子集
for(i in 1:dim(FMI)[1]){ + ifelse(cont[i,11] %in% FMI[,1],cont[i,43] <- TRUE, cont[i,43] <- FALSE) }
-
基于
cont$include
的子集
cont[,11] = cont$contributor_name
问题:目前,R正在非常努力地工作,但似乎没有改变列中的任何内容。我对我做错了什么感到困惑,因为我没有得到任何warnings()
或错误。
也许我是在尝试重新发明轮子,所以任何完成我开始做的事情的方法都会非常感激!
你不需要一个循环。这就是向量化要解决的问题。
FreqCon <- table(cont$contributor_name)
FMI <- names(FreqCon)[FreqCon > 4]
small_cont <- subset(cont, contributor_name %in% FMI)
听起来你只是想按频率进行子集。如果是这种情况,下面的代码应该可以工作:
mydf[mydf$V1 %in% names(which(table(mydf$V1) > 1)), ]
# V1 V2
# 4 s -0.30538839
# 5 e 1.51178117
# 7 s -0.62124058
# 11 e -0.01619026
逻辑是在"V1"列("contributor_name"为您的数据集)上运行table
,然后确定哪些符合您的条件(这里我将其设置为不止一次出现的任何"V1")。
不需要再创建一个列作为中间步骤。
如果这确实是您所追求的,并且您有大量数据,您可能需要考虑使用data.table
包:
> library(data.table)
> DT <- data.table(mydf)
> DT[, N := .N, by = "V1"][N > 1]
V1 V2 N
1: s -0.30538839 2
2: e 1.51178117 2
3: s -0.62124058 2
4: e -0.01619026 2
在上面的示例中,.N
类似于data.table
的table
,而确实创建了一个新列(在本例中名为"N")。语法与base R有点不同,但对于大数据应该更有效。
对于这些示例,mydf
的定义如下:
set.seed(1)
mydf <- data.frame(V1 = sample(letters[1:20], 12, replace = TRUE),
V2 = rnorm(12))
# V1 V2
# 1 f 0.48742905
# 2 h 0.73832471
# 3 l 0.57578135
# 4 s -0.30538839
# 5 e 1.51178117
# 6 r 0.38984324
# 7 s -0.62124058
# 8 n -2.21469989
# 9 m 1.12493092
# 10 b -0.04493361
# 11 e -0.01619026
# 12 d 0.94383621