【问题标题】:Assigning values through a loop通过循环赋值
【发布时间】:2020-12-11 16:49:41
【问题描述】:

我正在尝试衡量 Twitter 上的政治意识形态(通过使用 Rtweet)。我现在有一个数据框,其中包含 +100 个政治家 user_id 以及“因素 1”和“因素 2”的两个理想分数(两个因素的范围都是 1-4)。它看起来像这样(称为kandidat):

Navne Faktor 1 Faktor 2
"Politician1" 3.5 1.0
"Politician2" 2.0 4.0
Etc... X X

然后,我想检测随机 Twitter 用户是否关注我数据集中的一位或多位政客。如果他们例如关注我的数据集中的两位政客——“Politician1”和“Politician2”——然后,我将在这两个因素上为用户分配两位政客理想得分的平均值。一个 Twitter 用户关注这两位政客的例子可以是因子 1 = (3.5+1.0)/2 = 2.25 和因子 2 = (2.0+4.0)/2 = 3.00。

因此,我尝试创建一个简化的循环,其中仅包括来自 Twitter 的两名记者,称为“测试用户”,他们都关注我数据集中的大部分政治人物。然后循环应检查相应记者是否关注一位或多位政治家:如果他们关注,则循环应分配上述值的平均值。如果没有,它们应该自动从数据集中删除。下面的循环确实运行了,但不幸的是提供了错误的输出(参见代码下方的表格):

### loop ###

for(i in 1:ncol(testusers)){
  
  #pick politician1 of dataset
  politician1_friends <- get_friends(testusers$Navne[1])
  
  #intersect with candidate data
  ids_intersect = intersect(politician1_friends$user_id, kandidat$user_id)
  if(length(ids_intersect == 0)){
    testusers[i, "anyFriends"] <- FALSE #user has no friends in the politicians df
  } else {
    #assign values to user based on intersect
    politicians_friends = kandidat[kandidat$user_id %in% ids_intersect,]
    s1_mean <- mean(politicians_friends$faktor1, na.rm=TRUE)
    s2_mean <- mean(politicians_friends$faktor2, na.rm=TRUE)
    testusers[i, "faktor1"] <- s1_mean
    testusers[i, "faktor2"] <- s2_mean
    testusers[i, "anyFriends"] <- TRUE #user has friends in the politicians dataset
  }
  # etc.
}

上面的代码给了我这个输出:

Navne anyFriends
"Politician1" FALSE
"Politician2" NA

testusers的结构是:structure(list(Navne = c("Politician1", "Politician2"), anyFriends = c(FALSE, NA)), row.names = 1:2, class = "data.frame")。而且我无法发布 kandidat 的整个结构,因为它太大了:但它是一个由政客组成的数据框(包含来自函数 look_up() 的所有信息,例如 user_id、screen_name、text 等。

所以我猜代码需要一些小的改动,但我还没有弄明白。理想情况下,输出 (df) 应该由“仅”三个数据帧列组成:1) UserID/Name 2) Faktor1 3) Faktor2?

【问题讨论】:

  • 您的for 循环不会在任何地方使用i 索引。

标签: r loops


【解决方案1】:

我认为您想要的是另一个 data.frame 左右,其中包含您的用户和他们的“分数”。 R 喜欢使用此类数据帧而不是列表。

我现在假设,您有一个 data.frame 包含您的政治家等以及他们在两个维度上的得分,以及一个包含您感兴趣的用户的 data.frame,例如

kandidat <- data.frame(user_id = 1:2, name = c("Politician1", "Politican2"), Faktor1 = c(3.5, 2), Faktor2 = c(1,4))
my_users <- data.frame(name = c("Max", "Mara"))

现在,如果您想使用 for 循环,您可以执行类似的操作


find_f <- function(df){
  F1_mean <- c()
  F2_mean <- c()
  anyFriends <- c()
  
  for(i in 1:nrow(df)){
    #pick user1 of dataset
    user_friends <- get_friends(df$name[i])
    #intersect with our candidatedata
    ids_intersect = intersect(user_friends$user_id, politicians$user_id)
    if(length(ids_intersect)==0){
      anyFriends <- c(anyFriends, FALSE) # User has no friends in the politicians df
    } else {
      #assign values to user based on intersect - don't know what to do here
      kandidat_friends = kandidat[kandidat$user_id %in% ids_intersect,]
      F1_mean <- c(F1_mean, mean(kandidat_friends$Faktor1, na.rm=TRUE))
      F2_mean <- c(F2_mean, mean(kandidat_friends$Faktor2, na.rm=TRUE))
      anyFriends <- c(anyFriends, TRUE) # user has friends in the politicans dataset
    }
  }
  df$Faktor1 <- F1_mean
  df$Faktor2 <- F2_mean
  df$anyFriends <- anyFriends
  return(df[df$anyFriends,])
}

my_users2 <- find_f(my_users)

到目前为止,这不是一个非常简短的解决方案,但我认为它很容易理解。最重要的是,您使用 data.frames 而不是列表,这在 R 中要容易得多。在每次迭代中,我们都会获得用户的朋友,看看是否与政客有任何交集。如果不是,我们将布尔值FALSE 分配给my_users 数据帧中的anyFriends 变量,这样我们就可以轻松地将它们过滤掉。如果有交集,我们取所选政治家的两个分数的平均值,并将它们分配给相应的用户条目。

在我看来,不需要IDEOLOGISCORE 列表。另外,请注意我没有测试上面的代码,可能是有错别字。只需检查它是否适合您:)

【讨论】:

  • 能否提供reproducible example
  • 任何对此发表评论的人都需要知道testuserskandidat 的结构。例如,使用dput(testusers[1:5,]) 生成任何人都可以使用的输出。
  • testuserskandidat 的结构现在被添加到原始问题中并进行了简化。不幸的是,循环仍然没有以正确的方式赋值。
  • 我已经用一个应该可以工作的解决方案编辑了我的帖子(我已经用一个示例 user_friends 数据框对其进行了测试,但由于我不知道 user_friends 究竟是如何寻找你的,我可以不能确定。
  • 当只有两个人时,循环现在按预期工作!但是,当我抽取一个随机样本时,例如250 人并尝试运行循环,我立即结束了 get_friends 15 人网络限制(“警告:超出速率限制 - 88”)。所以我认为最后一步是包含某种 retryonratelimit = TRUESys.sleep() 函数?我认为这应该是the user_friends &lt;- get_friends(df$name[i]) 命令或my_users2 &lt;- find_f(my_users) 的延续,但我根本无法让它工作。我的循环代码与@Ben 发布的代码相同。
猜你喜欢
  • 1970-01-01
  • 2019-06-27
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
  • 2013-09-25
  • 2016-01-17
  • 2017-10-20
  • 2013-02-17
相关资源
最近更新 更多