2

我是R用户,我有一个关于我遇到的问题的问题:

  • 非常大的数据集(几乎 800k 行)
  • 该数据集列出了对美国 90 年代政治家的所有捐款

经过一些数据清理后,我需要将列表减小到更易于管理的大小。由于我对多次捐赠的贡献者感兴趣,因此我决定尝试像这样限制数据集的大小。

数据集加载为“cont”

我的意图:

  1. 地图提及频率:

    > table(cont$contributor_name) -> FreqCon
    > subset(FreqCon,Freq>4) -> FMI
    
  2. 插入一个额外的列作为 cont[,43],名称为“include”,表示 TRUE 或 FALSE 是否应该对其进行子集化

    for(i in 1:dim(FMI)[1]){
    + ifelse(cont[i,11] %in% FMI[,1],cont[i,43] <- TRUE, cont[i,43] <- FALSE) }
    
  3. 子集数据集基于cont$include

我希望这是所有相关信息。如果需要,我很乐意提供更多信息!还:cont[,11] = cont$contributor_name

问题:目前,R工作非常努力,但似乎没有改变列中的任何内容。我对自己做错了什么感到困惑,因为我没有收到任何warnings()错误。

也许我正在尝试重新发明轮子,所以任何完成我打算做的事情的方式都会非常感激!

4

2 回答 2

4

你不需要循环。这就是矢量化旨在解决的问题。

FreqCon <- table(cont$contributor_name)
FMI <- names(FreqCon)[FreqCon > 4]
small_cont <- subset(cont, contributor_name %in% FMI)
于 2013-04-16T11:24:05.880 回答
3

听起来您只是想按频率进行子集化。如果是这种情况,应该可以使用以下方法:

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

逻辑是只运行table“V1”列(您的数据集的“contributor_name”),然后确定哪些符合您的条件(这里我将其设置为任何多次出现的“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就像tablefordata.table并且确实创建了一个新列(在这种情况下,命名为“N”)。语法与基本 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
于 2013-04-16T11:23:25.343 回答