используйте цикл for, чтобы создать столбец, содержащий количество значений в другом столбце - PullRequest
0 голосов
/ 12 сентября 2018

Во-первых, я новичок в Stackoverflow и плохо знаком с R. Поэтому, пожалуйста, имейте меня в виду потенциальное недопонимание и тому подобное на моей стороне.

У меня есть фрейм данных с несколькими столбцами.Я пытаюсь создать новый столбец, который будет содержать количество значений в одном из других столбцов.В задаче указано, что мне нужно использовать цикл for для достижения этой цели, даже если это не самый эффективный или эффективный метод.

Я пробовал использовать этот подход, но по какой-то причине он не работает.

for (i in nrow(df)) {
   df$new_col[i] <- sum(df$old_col == df$old_col[i], na.rm = TRUE)
}

Если у вас есть такие данные:

old_col   name
   1       a
   1       b
   2       c
   3       d

Код должен дать:

old_col   name   new_col
   1       a        2
   1       b        2
   2       c        1
   3       d        1

Я благодарен за любую помощь!

Ответы [ 4 ]

0 голосов
/ 12 сентября 2018

Просто отсутствует 1: в строке for(i in 1:nrow(df)).

df <- 
tribble(
  ~old_col,   ~name,
  1,         "a",
  1,         "b",
  2,         "c",
  3,         "d")

df$new_col <- NA

for (i in 1:nrow(df)) {
  df$new_col[i] <- sum(df$old_col == df$old_col[i], na.rm = TRUE)
}

#         old_col name  new_col
#          <dbl> <chr>   <int>
#   1       1      a      2
#   2       1      b      2
#   3       2      c      1
#   4       3      d      1
0 голосов
/ 12 сентября 2018

Для вашего собственного кода просто измените nrow(df) на 1:nrow(df), и он должен прекрасно работать:

for (i in 1:nrow(df)) {
  df$new_col[i] <- sum(df$old_col == df$old_col[i], na.rm = TRUE)
}

Другой подход:

new_col=sapply(df$old_col,function(x) sum(df$old_col == x, na.rm = TRUE) )
df<-cbind(df,new_col)
0 голосов
/ 12 сентября 2018

Вы можете попробовать это (Решение для очень начинающих):

for(i in 1:nrow(df)){
  if(i==1){
   df$new_col[i]=1 # For first point
  }
  else if(df$old_col[i]==df$old_col[i-1]){
   df$new_col[i]=df$new_col[i-1]+1 # If old_col values are same
  }
  else{
   df$new_col[i]=1  # When we have a new old_col value
  }
} 

Выход:

    old_col name new_col
1       1    a       1
2       1    b       2
3       2    c       1
4       3    d       1
0 голосов
/ 12 сентября 2018

Что вам нужно, так это «подсчитать по группам» - сгруппировать по old_col и посчитать количество строк с этим значением old_col.

Это очень распространенная операция, и пакеты манипулирования данными позволяют легко это сделать. Мой личный выбор пакета данных - data.table, где ваша операция может быть выражена как:

library(data.table)
setDT(df) # convert to data.table to 'unlock' the correct syntax
df[ , new_col := .N, by = old_col]

С вашими данными:

df = data.frame(old_col = c(1, 1:3), name = letters[1:4])

выход:

   old_col name new_col
1:       1    a       2
2:       1    b       2
3:       2    c       1
4:       3    d       1

Если вы вынуждены сделать это с помощью цикла for, я настоятельно рекомендую не использовать 1:nrow(df). Вероятно, наиболее эффективным способом является использование table:

counts = as.data.frame(table(old_col = df$old_col))

for (ii in 1:nrow(counts)) {
  df$new_col[df$old_col == counts$old_col[ii]] = counts$Freq[ii]
}

Это позволяет избежать повторного подсчета количества строк - представьте, что в old_col у вас было 1 000 000 повторений 1. Вы не хотели бы считать до 1,000,000 миллиона раз (один раз для каждого появления 1); лучше посчитать 1 000 000 только один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...