Как я могу найти первый экземпляр NA в строке внутри фрейма данных? - PullRequest
0 голосов
/ 05 июня 2018

Как я могу увидеть, где (в каком столбце) первые NA появляются в строке во фрейме данных?

Я смотрю на точки, где участники выпадают в процессе, длина которого 10 шагов.

Каждый шаг идентифицируется в соответствующем столбце, то есть в общей сложности 10 столбцов.

Я могу определить, выполнил ли кто-нибудь какой-либо шаг, если я увижу значение даты и времени встолбец, который указывает момент, когда они завершили этот шаг.

Если они не завершили этот шаг, он отобразит NA, как и следующие столбцы.

Например, если ясм. NA в столбце 5 для конкретной строки, тогда я знаю, что этот конкретный пользователь не прошел этап 4, так как остальные столбцы также покажут NA.

Идея состоит в том, что участники завершают все 10шаги, означающие, что они полностью завершили процесс.

Я хочу иметь возможность определить наиболее распространенную точку высадки.

Мой набор данных имеет глубину 2000 строк - какя могу проверить и / или быстро идентифицировать это?

Пример данных:

structure(list(associate = c("tXQCMHwGFy", "JzObuwUnkJ", "2fM04XFVja", 
"uFsZTj2i2M", "ZsI0u5ka2j", "9r98DMXxFE", "NtmXw4qnIa", "oGB0Ugi93h", 
"G0r2yOxM7s", "MIpQqbBagS", "HCGJ5kSOlk", "3ljP9FuGcA", "5k7OvbBZUH", 
"6DDEbTWhBD", "xuU5Ewninw", "5UGABh3kcg", "G5etNVDoEH", "ejlCBv3dp2", 
"2DUWxEFt6o", "sCJeaxCSk5", "sb9QKBDSHl", "E8n3XZSS1x", "Ld7rFWFKag", 
"ykziBo9kOx", "Z9mOsGpDNE"), accountCreation = structure(c(1524606379.904, 
1528147858.812, 1521994536.637, 1522097826.043, 1528150007.134, 
1526575446.645, 1523493362.438, 1528123246.558, 1528135004.808, 
1527791947.924, 1526755863.609, 1525455650.394, 1523409400.766, 
1524347073.427, 1526134766.407, 1523638698.97, 1527878066.61, 
1524855389.236, 1526309009.378, 1520972884.396, 1527180696.03, 
1527268883.689, 1521646455.016, 1526837992.595, 1521040859.622
), class = c("POSIXct", "POSIXt")), profileSetup = structure(c(1524606693.345, 
1528148032.015, 1521994616.897, 1522097826.043, 1528186485.637, 
1526575497.987, 1523493556.798, 1528123314.197, 1528135180.95, 
1527792152.877, 1526756131.911, 1525455787.847, 1523409400.766, 
1524347073.427, 1526134850.566, 1523638905.289, 1527878482.462, 
1524855535.686, 1526309106.294, 1522186725.043, 1527180799.909, 
1527269009.143, 1521646455.016, 1526838102.323, 1521040859.622
), class = c("POSIXct", "POSIXt")), profilesetupDuration = c(314, 
174, 80, 0, 36478, 51, 194, 68, 176, 205, 268, 137, 0, 0, 84, 
207, 416, 146, 97, 1213841, 103, 126, 0, 110, 0), introductionSplash = structure(c(1524872052.263, 
1528148043.062, 1521995730.924, 1522097826.043, 1528186496.499, 
1526575506.96, 1523493567.959, 1528123329.044, 1528135237.755, 
1527792185.349, NA, 1525455815.855, 1523409400.766, 1524347073.427, 
1526134861.747, 1523638967.684, 1527878727.235, 1524855546.038, 
1526309117.104, 1522186739.397, NA, 1527269018.641, 1521646455.016, 
1526838112.374, 1521040859.622), class = c("POSIXct", "POSIXt"
)), introductionSplashDuration = c(265673, 185, 1194, 0, 36489, 
60, 205, 83, 233, 238, NA, 165, 0, 0, 95, 269, 661, 157, 108, 
1213855, NA, 135, 0, 120, 0), introduction = structure(c(1525124180.491, 
1528148744.594, 1521996568.337, 1522097826.043, NA, 1526576050.815, 
1523495507, 1528126805.572, NA, 1527792470.951, NA, 1525456759.777, 
1523409400.766, 1524347073.427, 1526135265.531, 1523639316.761, 
1527878956.368, 1524861227.537, 1526310376.89, 1522187755.31, 
NA, 1527269672.153, 1521646455.016, 1526838283.459, 1521040859.622
), class = c("POSIXct", "POSIXt")), introductionDuration = c(517801, 
886, 2032, 0, NA, 604, 2145, 3559, NA, 523, NA, 1109, 0, 0, 499, 
618, 890, 5838, 1367, 1214871, NA, 789, 0, 291, 0), demoChatSkipped = structure(c(NA, 
1528148761.447, NA, 1522097826.043, NA, 1526576060.249, NA, NA, 
NA, 1527792487.742, NA, 1525456803.893, 1523409400.766, 1524347073.427, 
1526147587.803, NA, NA, NA, NA, NA, NA, 1527269694.132, 1521646455.016, 
1526838287.934, 1521040859.622), class = c("POSIXct", "POSIXt"
)), demoChatSkippedDuration = c(NA, 903, NA, 0, NA, 614, NA, 
NA, NA, 540, NA, 1153, 0, 0, 12821, NA, NA, NA, NA, NA, NA, 811, 
0, 295, 0), approval = structure(c(1525124264.718, 1528148756.313, 
1522018833.517, 1522097826.043, NA, 1526576055.489, 1523538955.529, 
1528136805.681, NA, 1527792479.256, NA, 1525456805.673, 1523409400.766, 
1524347073.427, 1526147585.05, 1523639448.648, 1527879134.158, 
1524861732.505, 1526315087.819, 1522188033.261, 1527180827.746, 
1527269692.115, 1521646455.016, 1526838288.734, 1521040859.622
), class = c("POSIXct", "POSIXt")), approvalDuration = c(517885, 
898, 24297, 0, NA, 609, 45593, 13559, NA, 532, NA, 1155, 0, 0, 
12819, 750, 1068, 6343, 6078, 1215149, 131, 809, 0, 296, 0), 
    tutorial = structure(c(NA, NA, NA, 1522097826.043, NA, NA, 
    NA, NA, NA, NA, NA, NA, 1523409400.766, 1524347073.427, NA, 
    NA, NA, NA, NA, NA, NA, NA, 1521646455.016, NA, 1521040859.622
    ), class = c("POSIXct", "POSIXt")), tutorialDuration = c(NA, 
    NA, NA, 0, NA, NA, NA, NA, NA, NA, NA, NA, 0, 0, NA, NA, 
    NA, NA, NA, NA, NA, NA, 0, NA, 0), letsbegin = structure(c(1525124456.616, 
    1528148773.37, 1522031049.317, 1522097826.043, NA, 1526576071.6, 
    1523538956.159, 1528136822.297, NA, 1527794019.564, NA, 1525456849.582, 
    1523409400.766, 1524347073.427, 1526312517.824, 1523639449.148, 
    1527879134.675, 1524861750.153, 1526317200.235, 1522188066.352, 
    1527180828.158, NA, 1521646455.016, 1527015876.057, 1521040859.622
    ), class = c("POSIXct", "POSIXt")), letsbeginDuration = c(518077, 
    915, 36513, 0, NA, 625, 45594, 13576, NA, 2072, NA, 1199, 
    0, 0, 177751, 751, 1068, 6361, 8191, 1215182, 132, NA, 0, 
    177884, 0), demoChatDuration = c(517884, NA, 24297, NA, NA, 
    NA, 2499, 13559, NA, NA, NA, NA, NA, NA, 13201, 729, 1029, 
    6342, 6078, 1215148, NA, 967, NA, NA, NA)), row.names = c(937L, 
1941L, 396L, 30L, 1950L, 1337L, 602L, 1812L, 1872L, 1719L, 1423L, 
1077L, 173L, 234L, 1204L, 680L, 1748L, 989L, 1243L, 251L, 1568L, 
1615L, 196L, 1451L, 154L), class = "data.frame")

Ответы [ 6 ]

0 голосов
/ 05 июня 2018

Если вы хотите быстрое решение, я бы векторизовал это, используя max.col

res <- max.col(is.na(df), ties = "first") 

Хотя max.col вернет 1, даже если в конкретном случае не было NA сстрока.Следовательно, вы можете добавить следующую строку для обработки этих конкретных случаев

if(any(res == 1)) is.na(res) <- (res == 1) & !is.na(df[[1]])

Это преобразует эти случаи в NA - это означает, что индекс столбца для этой строки не был найден

0 голосов
/ 05 июня 2018

Рассмотрим фрейм данных, который имеет 7 строк и 3 столбца, с первым символом na в 4-м ряду 2-го столбца.

df <- read.table(text = "rowname  value test
                     A      3  8
                     B      1  3
                     C      2  8 
                     D     NA  5  
                     E      2  3
                     F      NA 4
                     G      6  9", header = TRUE)

Тогда положение первого значения na в кадре данных можно найти с помощью which и is.na.Например, первый индекс na найден в индексе 1. Можно выполнить цикл по каждому индексу, чтобы получить следующие nas по порядку.

pos_first_na <- which(is.na(df))[1]

Чтобы найти точную строку и столбцы:

col_pos <- pos_first_na %% ncol(df)

row_pos <- pos_first_na %% nrow(df)

 df[row_pos,col_pos]

Это дает:

> row_pos
[1] 4
> col_pos
[1] 2
> df[row_pos,col_pos]
[1] NA
0 голосов
/ 05 июня 2018

Если вы хотите, чтобы имя столбца было добавлено в ваш data.frame, то что-то вроде этого будет делать:

создаст некоторые данные, первые 10 записей mtcars.повторить вашу ситуацию с АН до конца.

df <- mtcars[1:10, ]
df[3, 3:11] <- NA
df[6, 5:11] <- NA

df$dropofpoint <- apply(df, 1, function(x) names(which(is.na(x)))[1])

head(df)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb dropofpoint
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4        <NA>
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4        <NA>
Datsun 710        22.8   4   NA  NA   NA    NA    NA NA NA   NA   NA        disp
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1        <NA>
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2        <NA>
Valiant           18.1   6  225 105   NA    NA    NA NA NA   NA   NA        drat
0 голосов
/ 05 июня 2018

В следующем коде я предполагаю, что вы хотите вернуть специальное значение, если в строке нет NA.

set.seed(5239)    # Make the results reproducible

dat <- matrix(1:40, 4)
dat[sample(40, 5)] <- NA
dat <- as.data.frame(dat)    # Not strictly needed

apply(dat, 1, function(x) {
    w <- which(is.na(x))
    if(length(w) > 0) min(w) else Inf
  })
#[1]   4   6 Inf   2

Специальное значение здесь Inf.Вы можете изменить это, например, на length(x) или на другое значение по вашему выбору.

0 голосов
/ 05 июня 2018

Вот пример:

## some fake data
Data <- matrix(c(0,0,0,NA,0,NA,NA,NA,0,0,NA,NA), nrow = 3, byrow = TRUE)

## which ones are the first NA's per row
## Edited to avoid the warning message
apply(Data,1, function(fo) ifelse(any(is.na(fo)),min(which(is.na(fo))), NA))

ура

Fer

0 голосов
/ 05 июня 2018
# Generate sample data
x <- t(apply(X = trees, MARGIN = 1, FUN = function(row) {
  row[sample(3, 1)] <- NA
  row
}))

na_index <- apply(X = x, MARGIN = 1, FUN = function(row) {
  which(is.na(row))
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...