首页 > 解决方案 > “如何获取字符串列表并根据另一列中的字符串插入新的数据框列?”

问题描述

我有棒球运动员的数据,想在他们的名字旁边插入一个新列,其中包含他们各自的学校。我在与数据框对应的列表中有学校名称。我想创建一个循环,一旦第一列到达字符串“Opponents:”,它将转到下一所学校,我需要什么循环来完成这个?

我试过使用 and if then else 语句,以及 next 将学校插入列中。

schools <- c("College of Idaho","Aquinas","Avila","Baker")

df$School <- for (i in nrow(df)) 
if(df$Name!="Opponents:") {
schools[1]
else 
next schools
}

我希望我的 df 看起来像这样:

    Name           School
    Van, Austin   College of Idaho
    Lewis, Payton College of Idaho
    ....
    Opponents:     College of Idaho
    Overbeek, Alec Aquinas
    Haran, Noah    Aquinas

标签: rloops

解决方案


你有一些问题。最大的一个是您不在i循环中使用,因此在不同的迭代中没有任何变化。

df$School <- for 

这一般是行不通的。for()不返回任何内容,您需要在循环内进行赋值。

for (i in nrow(df)) 

这是一个常见的错字。你想要for (i in 1:nrow(df)),否则只会有一次迭代。

if(df$Name!="Opponents:") {

这里有两个问题:(a)df$Name是整个列,我们希望它是i特定的。(b) 从您的样本结果来看,您仍然希望将学校分配到“Opponents:”行。所以我们需要确保这种情况发生。

schools[1]

这是不好的。schools[1]"College of Idaho"。你希望这能够改变到不同的学校,而不是总是成为第一所学校。

else 
next schools
}

next立即进入下一个迭代。之后它schools什么也不做。

这是一个工作循环(未经测试,因为您的数据不可复制/粘贴):

current_school = 1
for (i in 1:nrow(df)) {
  df$Schools[i] = schools[current_school]
  if(df$Name == "Opponents:") {
    current_school = current_school + 1
  }
}

但我们不喜欢循环。这是一种更巧妙的方法:首先,我们将“Opponents:”行累加起来,然后我们将其偏移 1(这样“Opponents:”行与上面的行获得相同的学校),然后我们可以一次完成所有任务:

opp_count = cumsum(df$Name == "Opponents:") + 1  # count "Opponents:" rows, starting from 1
opp_count = c(1, opp_count[-nrow(df)]) # offset by 1
df$School = schools[opp_count] # use this to index the schools vector for assignment

我没有测试这些解决方案,因为您的数据不是易于导入的格式。如果您分享dput(droplevels(df[1:20, c("Name", "School")])),那将提供您的数据框的副本/可粘贴版本,我很乐意进行测试和调试。


推荐阅读