Вставить значения во фрейм данных в al oop R - PullRequest
0 голосов
/ 05 мая 2020

Я хочу вставить в столбец пребывания значение, полученное с помощью этой функции. Это df (df содержит более 85000000 строк с разными mac_address и сенсорами):

> head(df)
                        id   device_type direction       mac_address
1 5b83072ce72db73f1c3dd874 Mobile device     input 00:00:00:00:00:00
2 5b83077ce72db73f1c3dd902 Mobile device    output 00:00:00:00:00:00
3 5b832c45e72db73f1c3e0550 Mobile device     input 00:00:00:00:00:00
4 5b832c96e72db73f1c3e0589 Mobile device    output 00:00:00:00:00:00
5 5b83f783e72db73f1c3f0847 Mobile device     input 00:00:00:00:00:00
6 5b83f7d4e72db73f1c3f08f7 Mobile device    output 00:00:00:00:00:00
  processed_status rssi signal_type          fecha_hora sensor      uTime stay
1            FALSE  -72          WF 2018-08-26 22:00:08    3_2 1535313608   -1
2            FALSE  -90          WF 2018-08-26 22:01:54    3_2 1535313714   -1
3            FALSE  -71          WF 2018-08-27 00:38:21    3_2 1535323101   -1
4            FALSE  -90          WF 2018-08-27 00:40:10    3_2 1535323210   -1
5            FALSE  -74          WF 2018-08-27 15:06:03    3_2 1535375163   -1
6            FALSE  -90          WF 2018-08-27 15:07:40    3_2 1535375260   -1

И это функция, которая получает кластер для каждого mac_addres и сенсора и следующую ошибку:

> mac <- as.data.frame(unique(df$mac_address))
> sens <- as.data.frame(unique(df$sensor))
> for (i in 1:nrow(mac)) {
+   for (j in 1:nrow(sens)) {
+     cluster <- dbscan(df[df$mac_address == mac[i,] & df$sensor == sens[j,], ]$uTime, eps = 300, MinPts = 2)
+    df$stay <- cbind(df[df$mac_address == mac[i,] & df$sensor == sens[j,], ], stay = cluster$cluster)
+ #Add the cluster$cluster to the df 
+       
+   }
+ }
Error in `$<-.data.frame`(`*tmp*`, "stay", value = list(id = c(1755538L,  : 
replacement has 16 rows, data has 8324325

С помощью этой функции я получаю значение кластера для каждого отдельного mac_address и датчика. Но я не могу добавить этот номер кластера в df, потому что в l oop он повторяется mac_address и sensor, и это дает мне следующую ошибку.

Не знаю, есть ли лучший способ сделать это, но это то, что я придумал.

Заранее спасибо.

1 Ответ

0 голосов
/ 05 мая 2020

По сути, вы назначаете нефильтрованный столбец фрейма данных по отфильтрованным данным, в результате вызывается cbind, где обе стороны имеют разные строки:

df$stay <- cbind(df[df$mac_address == mac[i,] & df$sensor == sens[j,], ], 
                 stay = cluster$cluster)

Кроме того, предполагая, что dbScan из того же имени пакет, Документы CRAN указывают, что возвращаемое значение:

Объект класса dbscan_fast со следующими компонентами:

eps значение параметра eps. minPts значение параметра minPts. кластер Целочисленный вектор с назначениями кластера. Ноль указывает на точки шума.

Что может расширять объект R list этими именованными компонентами вектора, а не одним значением. Кроме того, ваш фильтр фрейма данных может не возвращать строк, поскольку может не быть экземпляров указанного c уникального значения mac_address И sensor . В целом, у вас есть проблемы с длиной с обеих сторон присваивания.

Чтобы исправить это, рассмотрите возможность обертывания вычисления в tryCatch и, в частности, выбора значения eps. Также рассмотрите expand.grid и Map для поэлементного цикла вместо вложенных for циклов, в которых вы создаете промежуточный фрейм данных, который объединяется обратно в более крупный:

# DATA FRAME OF ALL POSSIBLE COMBINATIONS
params_df <- expand.grid(mac_address = unique(df$mac_address),
                         sensor = unique(df$sensor))

# USER-DEFINED METHOD WITH tryCatch FOR FAILED CALCULATIONS
calc_cluster <- function(mac, sens) {
    tryCatch({
       sub <- df[df$mac_address == mac & df$sensor == sens,]
       dbscan(sub$uTime, eps = 300, MinPts = 2)$eps
     }, error = function(e) return(NA)
    )
}

# COLUMN ASSIGNMENT
params_df$cluster <- Map(calc_cluster, params_df$mac_address, params_df$sensor)

# MERGE TO ORIGINAL DATA FRAME
df <- merge(df, params_df, by=c("mac_address", "sensor"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...