Как написать цикл для в с Nrow? - PullRequest
0 голосов
/ 24 мая 2019

У меня есть набор данных, называемый "поездка", включающий 900 000 записей, показывающих поездки.У меня есть столбец с именем «ID», который показывает идентификатор человека для человека.Тем не менее, вот в чем дело.У одного человека может быть 1 поездка, поэтому для этого идентификатора есть только одна запись, но у другого человека может быть 7 поездок, в результате чего будет 7 строк (с тем же идентификатором).Затем у меня есть столбец под названием «Транспортный режим», который может иметь значения 1 (для автомобиля), 2 (для общественного транспорта), 3 (для прогулки) и 4 (для велосипеда), показывая различные варианты транспорта.Вот мои переменные:

ID: c (30001, 30002, 30002, 30002, 30002, 30002, 30002, 30002)

Затем у меня есть столбец с именем Transport_mode, относящийся к этим идентификаторам(поездки)

Transport_mode: c (1, 2, 4, 3, 2, 1, 2, 1)

Итак, я сделал пустую переменную public_fr для отображения частотыпоездок на общественном транспорте.Я хочу написать цикл, который подсчитывает количество общественного транспорта для любого идентификатора.Итак, я попробовал следующее:

for (i in 1:nrow(trip))
   {for (j in 1:nrow(trip$ID))
     {if (as.character(trip$Transport_mode[j] == 2)) (trip$public_fr[j] <- trip$public_fr[j] + 1)}

Этот код должен дать мне:

public_fr: c (0, 3)

0: потому что ID = 30001 не имеетпоездка на общественном транспорте (посмотрите на транспортный режим 1) и 3: потому что ID = 30002 имеет три поездки на общественном транспорте (потому что есть три 2). Однако, это не работает.Это дает ошибку:

Ошибка в 1: nrow (trip $ ID): аргумент длины 0

Можете ли вы помочь мне с этим?если есть аналогичный вопрос, пожалуйста, приведите ссылку.Благодаря.

Ответы [ 3 ]

2 голосов
/ 24 мая 2019

Вы можете сделать это в базе R, используя aggregate.

aggregate(trip$Transport_mode == 2, list(trip$ID), sum)$x
[1] 0 3
1 голос
/ 24 мая 2019

Если trip дается кодом в примечании в конце, то это дает таблицу подсчета идентификатора и режима:

table(trip)

, давая:

       Transport_mode
ID      1 2 3 4
  30001 1 0 0 0
  30002 1 3 1 1

Примечание

trip <- data.frame(
  ID = c(30001, 30002, 30002, 30002, 30002, 30002, 30002),
  Transport_mode = c(1, 2, 4, 3, 2, 1, 2))
0 голосов
/ 24 мая 2019

Ваша ошибка в том, что trip$ID - это просто вектор, а в векторах нет строк. nrow(trip$ID) выдаст NULL, а 1:NULL выдаст ошибку, которую вы видите.

В общем, цикл for - плохой способ сделать это. Есть много хороших способов сделать что-то «по группам» во фрейме данных, например, в пакетах base::aggregate или dplyr и data.table. Вот dplyr версия вашего кода:

library(dplyr)
trip %>%
  group_by(ID) %>%
  summarize(public_fr = sum(Transport_mode == 2))

В общем, sum(condition) - это хороший способ подсчитать, сколько раз условие выполняется, например, sum(Transport_mode == 2) в этом случае.

Если вы действительно хотите использовать цикл for (вы не должны - это труднее писать и намного медленнее), вам следует зацикливаться на уникальных значениях идентификаторов, а не на каждой строке :

uid = unique(trip$ID)
public_fr = integer(length(uid))
for(i in 1:length(uid)) {
  public_fr[i] = sum(trip[trip$ID == uid[i], "Transport_mode"] == 2)
}

Вышеприведенный цикл просматривает каждый уникальный ID, извлекает значения Transport_mode, соответствующие этому идентификатору, и использует трюк sum для подсчета 2-х. Но в R это плохой путь. aggregate, dplyr или data.table намного лучше.

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